From 0c13c2b6e2176d6861680409f934f8379259db42 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 13 Nov 2017 16:37:28 +0100 Subject: [PATCH 001/109] Remove unused QQC1 imports --- .../QtWebEngine/UIDelegates/AlertDialog.qml | 2 -- .../resources/QtWebEngine/UIDelegates/FilePicker.qml | 2 -- interface/resources/QtWebEngine/UIDelegates/Menu.qml | 1 - .../resources/QtWebEngine/UIDelegates/MenuItem.qml | 2 -- .../QtWebEngine/UIDelegates/PromptDialog.qml | 2 -- interface/resources/qml/AvatarInputs.qml | 3 --- interface/resources/qml/Browser.qml | 1 - interface/resources/qml/LoginDialog/SignUpBody.qml | 1 - .../qml/LoginDialog/UsernameCollisionBody.qml | 1 - interface/resources/qml/QmlWebWindow.qml | 1 - interface/resources/qml/QmlWindow.qml | 5 ----- interface/resources/qml/StatText.qml | 1 - interface/resources/qml/Stats.qml | 1 - interface/resources/qml/TabletBrowser.qml | 1 - interface/resources/qml/Web3DOverlay.qml | 1 - interface/resources/qml/controller/AnalogButton.qml | 3 --- interface/resources/qml/controller/AnalogStick.qml | 3 --- interface/resources/qml/controller/Hydra.qml | 3 --- interface/resources/qml/controller/Standard.qml | 3 --- interface/resources/qml/controller/ToggleButton.qml | 3 --- interface/resources/qml/controller/Xbox.qml | 3 --- .../resources/qml/controller/hydra/HydraButtons.qml | 3 --- .../resources/qml/controller/hydra/HydraStick.qml | 3 --- interface/resources/qml/controller/xbox/DPad.qml | 3 --- .../qml/controller/xbox/LeftAnalogStick.qml | 3 --- .../qml/controller/xbox/RightAnalogStick.qml | 3 --- .../resources/qml/controller/xbox/XboxButtons.qml | 3 --- .../resources/qml/controls-uit/HorizontalRule.qml | 2 -- .../resources/qml/controls-uit/ImageMessageBox.qml | 1 - .../resources/qml/controls-uit/QueuedButton.qml | 2 -- .../resources/qml/controls-uit/TabletHeader.qml | 1 - interface/resources/qml/controls-uit/TextAction.qml | 2 -- interface/resources/qml/controls-uit/TextEdit.qml | 2 -- interface/resources/qml/controls/FontAwesome.qml | 2 -- interface/resources/qml/dialogs/AssetDialog.qml | 1 - interface/resources/qml/dialogs/MessageDialog.qml | 1 - .../resources/qml/dialogs/PreferencesDialog.qml | 1 - .../resources/qml/dialogs/TabletAssetDialog.qml | 1 - .../qml/dialogs/TabletConnectionFailureDialog.qml | 1 - .../resources/qml/dialogs/TabletLoginDialog.qml | 1 - interface/resources/qml/dialogs/TabletMessageBox.qml | 1 - .../dialogs/messageDialog/MessageDialogButton.qml | 1 - .../qml/dialogs/preferences/AvatarBrowser.qml | 1 - .../qml/dialogs/preferences/ComboBoxPreference.qml | 2 -- .../resources/qml/dialogs/preferences/Preference.qml | 1 - interface/resources/qml/hifi/ComboDialog.qml | 1 - .../resources/qml/hifi/DesktopLetterboxMessage.qml | 1 - interface/resources/qml/hifi/LetterboxMessage.qml | 1 - interface/resources/qml/hifi/audio/InputPeak.qml | 2 -- interface/resources/qml/hifi/audio/MicBar.qml | 2 -- .../qml/hifi/commerce/common/CommerceLightbox.qml | 1 - .../commerce/common/EmulatedMarketplaceHeader.qml | 1 - .../qml/hifi/commerce/common/FirstUseTutorial.qml | 1 - .../inspectionCertificate/InspectionCertificate.qml | 1 - .../qml/hifi/commerce/purchases/Purchases.qml | 1 - .../qml/hifi/commerce/wallet/NeedsLogIn.qml | 1 - .../qml/hifi/commerce/wallet/PassphraseChange.qml | 1 - .../qml/hifi/commerce/wallet/PassphraseModal.qml | 1 - .../qml/hifi/commerce/wallet/PassphraseSelection.qml | 1 - .../resources/qml/hifi/commerce/wallet/Security.qml | 1 - .../qml/hifi/commerce/wallet/SecurityImageChange.qml | 1 - .../hifi/commerce/wallet/SecurityImageSelection.qml | 1 - .../resources/qml/hifi/commerce/wallet/SendMoney.qml | 1 - .../resources/qml/hifi/commerce/wallet/Wallet.qml | 1 - .../qml/hifi/commerce/wallet/WalletSetup.qml | 1 - .../resources/qml/hifi/dialogs/AttachmentsDialog.qml | 1 - .../qml/hifi/dialogs/ModelBrowserDialog.qml | 1 - .../resources/qml/hifi/dialogs/TabletDCDialog.qml | 1 - .../qml/hifi/dialogs/TabletEntityStatistics.qml | 1 - .../qml/hifi/dialogs/TabletEntityStatisticsItem.qml | 2 -- .../resources/qml/hifi/dialogs/TabletLODTools.qml | 2 -- .../qml/hifi/dialogs/attachments/Attachment.qml | 4 ---- .../qml/hifi/dialogs/attachments/Vector3.qml | 1 - .../resources/qml/hifi/overlays/ImageOverlay.qml | 1 - interface/resources/qml/hifi/overlays/Overlay.qml | 1 - .../resources/qml/hifi/overlays/RectangleOverlay.qml | 1 - .../resources/qml/hifi/overlays/TextOverlay.qml | 1 - .../resources/qml/hifi/tablet/CalibratingScreen.qml | 5 +---- .../resources/qml/hifi/tablet/InputRecorder.qml | 2 -- .../resources/qml/hifi/tablet/NewModelDialog.qml | 1 - .../qml/hifi/tablet/OpenVrConfiguration.qml | 12 +----------- .../qml/hifi/tablet/TabletAttachmentsDialog.qml | 1 - .../resources/qml/hifi/tablet/TabletMenuItem.qml | 1 - .../resources/qml/hifi/tablet/TabletMenuView.qml | 2 -- .../qml/hifi/tablet/TabletModelBrowserDialog.qml | 1 - interface/resources/qml/hifi/tablet/TabletRoot.qml | 1 - .../tablet/tabletWindows/TabletPreferencesDialog.qml | 4 ---- .../tablet/tabletWindows/preferences/Preference.qml | 1 - .../tablet/tabletWindows/preferences/Section.qml | 1 - .../preferences/TabletAvatarBrowser.qml | 1 - interface/resources/qml/hifi/toolbars/StateImage.qml | 1 - interface/resources/qml/hifi/toolbars/Toolbar.qml | 1 - .../resources/qml/hifi/toolbars/ToolbarButton.qml | 1 - .../resources/qml/styles-uit/AnonymousProRegular.qml | 2 -- interface/resources/qml/styles-uit/ButtonLabel.qml | 2 -- .../resources/qml/styles-uit/FiraSansRegular.qml | 2 -- .../resources/qml/styles-uit/FiraSansSemiBold.qml | 2 -- interface/resources/qml/styles-uit/IconButton.qml | 2 -- interface/resources/qml/styles-uit/InfoItem.qml | 2 -- interface/resources/qml/styles-uit/InputLabel.qml | 2 -- interface/resources/qml/styles-uit/ListItem.qml | 2 -- interface/resources/qml/styles-uit/Logs.qml | 2 -- interface/resources/qml/styles-uit/OverlayTitle.qml | 2 -- interface/resources/qml/styles-uit/RalewayBold.qml | 2 -- interface/resources/qml/styles-uit/RalewayLight.qml | 2 -- .../resources/qml/styles-uit/RalewayRegular.qml | 2 -- .../resources/qml/styles-uit/RalewaySemiBold.qml | 2 -- interface/resources/qml/styles-uit/SectionName.qml | 2 -- interface/resources/qml/styles-uit/ShortcutText.qml | 2 -- interface/resources/qml/styles-uit/TabName.qml | 2 -- .../resources/qml/styles-uit/TextFieldInput.qml | 2 -- interface/resources/qml/windows/DefaultFrame.qml | 1 - interface/resources/qml/windows/Fadable.qml | 2 -- .../resources/qml/windows/TabletModalWindow.qml | 3 --- interface/resources/qml/windows/Window.qml | 2 -- 115 files changed, 2 insertions(+), 202 deletions(-) diff --git a/interface/resources/QtWebEngine/UIDelegates/AlertDialog.qml b/interface/resources/QtWebEngine/UIDelegates/AlertDialog.qml index e6dc03fa55..bf72869752 100644 --- a/interface/resources/QtWebEngine/UIDelegates/AlertDialog.qml +++ b/interface/resources/QtWebEngine/UIDelegates/AlertDialog.qml @@ -1,6 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Layouts 1.0 import "../../qml/dialogs" diff --git a/interface/resources/QtWebEngine/UIDelegates/FilePicker.qml b/interface/resources/QtWebEngine/UIDelegates/FilePicker.qml index cb6552b075..55f7d27534 100644 --- a/interface/resources/QtWebEngine/UIDelegates/FilePicker.qml +++ b/interface/resources/QtWebEngine/UIDelegates/FilePicker.qml @@ -1,6 +1,4 @@ import QtQuick 2.4 -import QtQuick.Dialogs 1.1 -import QtQuick.Controls 1.4 import "../../qml/dialogs" diff --git a/interface/resources/QtWebEngine/UIDelegates/Menu.qml b/interface/resources/QtWebEngine/UIDelegates/Menu.qml index 1bbbbd6cbe..46c00e758e 100644 --- a/interface/resources/QtWebEngine/UIDelegates/Menu.qml +++ b/interface/resources/QtWebEngine/UIDelegates/Menu.qml @@ -1,5 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 as Controls import "../../qml/controls-uit" import "../../qml/styles-uit" diff --git a/interface/resources/QtWebEngine/UIDelegates/MenuItem.qml b/interface/resources/QtWebEngine/UIDelegates/MenuItem.qml index 1890fcb81d..6014b6834b 100644 --- a/interface/resources/QtWebEngine/UIDelegates/MenuItem.qml +++ b/interface/resources/QtWebEngine/UIDelegates/MenuItem.qml @@ -1,6 +1,4 @@ - import QtQuick 2.5 -import QtQuick.Controls 1.4 as Controls import "../../qml/controls-uit" import "../../qml/styles-uit" diff --git a/interface/resources/QtWebEngine/UIDelegates/PromptDialog.qml b/interface/resources/QtWebEngine/UIDelegates/PromptDialog.qml index 01d3262bc0..e4ab3037ef 100644 --- a/interface/resources/QtWebEngine/UIDelegates/PromptDialog.qml +++ b/interface/resources/QtWebEngine/UIDelegates/PromptDialog.qml @@ -1,6 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Layouts 1.0 import "../../qml/controls-uit" import "../../qml/styles-uit" diff --git a/interface/resources/qml/AvatarInputs.qml b/interface/resources/qml/AvatarInputs.qml index be4bf03465..5001cb79e5 100644 --- a/interface/resources/qml/AvatarInputs.qml +++ b/interface/resources/qml/AvatarInputs.qml @@ -8,9 +8,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.4 -import QtQuick.Controls 1.3 -import QtGraphicalEffects 1.0 -import Qt.labs.settings 1.0 import "./hifi/audio" as HifiAudio diff --git a/interface/resources/qml/Browser.qml b/interface/resources/qml/Browser.qml index 55927fda24..aa01e6e5a0 100644 --- a/interface/resources/qml/Browser.qml +++ b/interface/resources/qml/Browser.qml @@ -1,5 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.2 import QtWebChannel 1.0 import QtWebEngine 1.2 diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index 9d55998b40..5eb99e0ece 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -11,7 +11,6 @@ import Hifi 1.0 import QtQuick 2.7 import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 as OriginalStyles import "../controls-uit" import "../styles-uit" diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml index 5c212578b8..bf05a36ce1 100644 --- a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml +++ b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml @@ -11,7 +11,6 @@ import Hifi 1.0 import QtQuick 2.4 import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 as OriginalStyles import "../controls-uit" import "../styles-uit" diff --git a/interface/resources/qml/QmlWebWindow.qml b/interface/resources/qml/QmlWebWindow.qml index d2daf0fa1d..d73a574081 100644 --- a/interface/resources/qml/QmlWebWindow.qml +++ b/interface/resources/qml/QmlWebWindow.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtWebEngine 1.1 import QtWebChannel 1.0 diff --git a/interface/resources/qml/QmlWindow.qml b/interface/resources/qml/QmlWindow.qml index 9a84418b3a..f1ef1464d3 100644 --- a/interface/resources/qml/QmlWindow.qml +++ b/interface/resources/qml/QmlWindow.qml @@ -1,9 +1,4 @@ - import QtQuick 2.3 -import QtQuick.Controls 1.4 -import QtWebChannel 1.0 -import QtWebEngine 1.2 -import QtWebSockets 1.0 import "windows" as Windows import "controls" diff --git a/interface/resources/qml/StatText.qml b/interface/resources/qml/StatText.qml index 69963c1373..9fefbd28b8 100644 --- a/interface/resources/qml/StatText.qml +++ b/interface/resources/qml/StatText.qml @@ -1,5 +1,4 @@ import QtQuick 2.3 -import QtQuick.Controls 1.2 Text { color: "white"; diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 4626d9bcda..d961285a46 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -1,6 +1,5 @@ import Hifi 1.0 as Hifi import QtQuick 2.3 -import QtQuick.Controls 1.2 import '.' Item { diff --git a/interface/resources/qml/TabletBrowser.qml b/interface/resources/qml/TabletBrowser.qml index 8dbcc8f4f8..141c1f25a7 100644 --- a/interface/resources/qml/TabletBrowser.qml +++ b/interface/resources/qml/TabletBrowser.qml @@ -1,5 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtWebChannel 1.0 import QtWebEngine 1.5 diff --git a/interface/resources/qml/Web3DOverlay.qml b/interface/resources/qml/Web3DOverlay.qml index a1fa2d2641..fdd5d8a7c6 100644 --- a/interface/resources/qml/Web3DOverlay.qml +++ b/interface/resources/qml/Web3DOverlay.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "controls" as Controls diff --git a/interface/resources/qml/controller/AnalogButton.qml b/interface/resources/qml/controller/AnalogButton.qml index 82beb818ab..6539bc793d 100644 --- a/interface/resources/qml/controller/AnalogButton.qml +++ b/interface/resources/qml/controller/AnalogButton.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 Item { id: root diff --git a/interface/resources/qml/controller/AnalogStick.qml b/interface/resources/qml/controller/AnalogStick.qml index c0d10bac59..d7b52a6319 100644 --- a/interface/resources/qml/controller/AnalogStick.qml +++ b/interface/resources/qml/controller/AnalogStick.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 Item { id: root diff --git a/interface/resources/qml/controller/Hydra.qml b/interface/resources/qml/controller/Hydra.qml index 19f3b4c193..e5c918cc77 100644 --- a/interface/resources/qml/controller/Hydra.qml +++ b/interface/resources/qml/controller/Hydra.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import "hydra" diff --git a/interface/resources/qml/controller/Standard.qml b/interface/resources/qml/controller/Standard.qml index 45e4febfa2..1c51a527cd 100644 --- a/interface/resources/qml/controller/Standard.qml +++ b/interface/resources/qml/controller/Standard.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import "xbox" diff --git a/interface/resources/qml/controller/ToggleButton.qml b/interface/resources/qml/controller/ToggleButton.qml index ee8bd380e2..567191bd25 100644 --- a/interface/resources/qml/controller/ToggleButton.qml +++ b/interface/resources/qml/controller/ToggleButton.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 Item { id: root diff --git a/interface/resources/qml/controller/Xbox.qml b/interface/resources/qml/controller/Xbox.qml index 4ff2959129..71f99c2081 100644 --- a/interface/resources/qml/controller/Xbox.qml +++ b/interface/resources/qml/controller/Xbox.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import "xbox" diff --git a/interface/resources/qml/controller/hydra/HydraButtons.qml b/interface/resources/qml/controller/hydra/HydraButtons.qml index aa8927f5b6..f579527a1f 100644 --- a/interface/resources/qml/controller/hydra/HydraButtons.qml +++ b/interface/resources/qml/controller/hydra/HydraButtons.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import ".." diff --git a/interface/resources/qml/controller/hydra/HydraStick.qml b/interface/resources/qml/controller/hydra/HydraStick.qml index d082a20b10..7b5ce41c76 100644 --- a/interface/resources/qml/controller/hydra/HydraStick.qml +++ b/interface/resources/qml/controller/hydra/HydraStick.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import ".." diff --git a/interface/resources/qml/controller/xbox/DPad.qml b/interface/resources/qml/controller/xbox/DPad.qml index 2cfb6412e7..20eda19648 100644 --- a/interface/resources/qml/controller/xbox/DPad.qml +++ b/interface/resources/qml/controller/xbox/DPad.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import ".." diff --git a/interface/resources/qml/controller/xbox/LeftAnalogStick.qml b/interface/resources/qml/controller/xbox/LeftAnalogStick.qml index 8e2de1eb36..430d6f39a4 100644 --- a/interface/resources/qml/controller/xbox/LeftAnalogStick.qml +++ b/interface/resources/qml/controller/xbox/LeftAnalogStick.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import ".." diff --git a/interface/resources/qml/controller/xbox/RightAnalogStick.qml b/interface/resources/qml/controller/xbox/RightAnalogStick.qml index 0cdfeda2cf..89e93aa8bc 100644 --- a/interface/resources/qml/controller/xbox/RightAnalogStick.qml +++ b/interface/resources/qml/controller/xbox/RightAnalogStick.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import ".." diff --git a/interface/resources/qml/controller/xbox/XboxButtons.qml b/interface/resources/qml/controller/xbox/XboxButtons.qml index e26a4a0b98..5c68fcff72 100644 --- a/interface/resources/qml/controller/xbox/XboxButtons.qml +++ b/interface/resources/qml/controller/xbox/XboxButtons.qml @@ -1,7 +1,4 @@ import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtQuick.Dialogs 1.0 import ".." diff --git a/interface/resources/qml/controls-uit/HorizontalRule.qml b/interface/resources/qml/controls-uit/HorizontalRule.qml index 425500f1d4..0609cc451d 100644 --- a/interface/resources/qml/controls-uit/HorizontalRule.qml +++ b/interface/resources/qml/controls-uit/HorizontalRule.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 Rectangle { anchors.left: parent.left diff --git a/interface/resources/qml/controls-uit/ImageMessageBox.qml b/interface/resources/qml/controls-uit/ImageMessageBox.qml index 95c753aab4..74313f7ffe 100644 --- a/interface/resources/qml/controls-uit/ImageMessageBox.qml +++ b/interface/resources/qml/controls-uit/ImageMessageBox.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../styles-uit" Item { diff --git a/interface/resources/qml/controls-uit/QueuedButton.qml b/interface/resources/qml/controls-uit/QueuedButton.qml index 36ffbe582f..6612d582df 100644 --- a/interface/resources/qml/controls-uit/QueuedButton.qml +++ b/interface/resources/qml/controls-uit/QueuedButton.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 import "../styles-uit" import "." as HifiControls diff --git a/interface/resources/qml/controls-uit/TabletHeader.qml b/interface/resources/qml/controls-uit/TabletHeader.qml index 17530f81ea..56203de286 100644 --- a/interface/resources/qml/controls-uit/TabletHeader.qml +++ b/interface/resources/qml/controls-uit/TabletHeader.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../styles-uit" diff --git a/interface/resources/qml/controls-uit/TextAction.qml b/interface/resources/qml/controls-uit/TextAction.qml index 1c66c3630a..1745a6c273 100644 --- a/interface/resources/qml/controls-uit/TextAction.qml +++ b/interface/resources/qml/controls-uit/TextAction.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "../styles-uit" import "../controls-uit" as HifiControls diff --git a/interface/resources/qml/controls-uit/TextEdit.qml b/interface/resources/qml/controls-uit/TextEdit.qml index 5ee9ce94ba..d03dcbbac6 100644 --- a/interface/resources/qml/controls-uit/TextEdit.qml +++ b/interface/resources/qml/controls-uit/TextEdit.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "../styles-uit" TextEdit { diff --git a/interface/resources/qml/controls/FontAwesome.qml b/interface/resources/qml/controls/FontAwesome.qml index 50d7e96fb5..c0f7fbb5fe 100644 --- a/interface/resources/qml/controls/FontAwesome.qml +++ b/interface/resources/qml/controls/FontAwesome.qml @@ -1,6 +1,4 @@ import QtQuick 2.3 -import QtQuick.Controls 1.3 -import QtQuick.Controls.Styles 1.3 Text { id: root diff --git a/interface/resources/qml/dialogs/AssetDialog.qml b/interface/resources/qml/dialogs/AssetDialog.qml index 8d19d38efb..e8d28e9b37 100644 --- a/interface/resources/qml/dialogs/AssetDialog.qml +++ b/interface/resources/qml/dialogs/AssetDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import Qt.labs.settings 1.0 import "../styles-uit" diff --git a/interface/resources/qml/dialogs/MessageDialog.qml b/interface/resources/qml/dialogs/MessageDialog.qml index 40c5a01e15..d7549f664b 100644 --- a/interface/resources/qml/dialogs/MessageDialog.qml +++ b/interface/resources/qml/dialogs/MessageDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtQuick.Dialogs 1.2 as OriginalDialogs import "../controls-uit" diff --git a/interface/resources/qml/dialogs/PreferencesDialog.qml b/interface/resources/qml/dialogs/PreferencesDialog.qml index e16f3aa12d..601f350ed5 100644 --- a/interface/resources/qml/dialogs/PreferencesDialog.qml +++ b/interface/resources/qml/dialogs/PreferencesDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../controls-uit" as HifiControls import "../styles-uit" diff --git a/interface/resources/qml/dialogs/TabletAssetDialog.qml b/interface/resources/qml/dialogs/TabletAssetDialog.qml index 016deec094..897378e40c 100644 --- a/interface/resources/qml/dialogs/TabletAssetDialog.qml +++ b/interface/resources/qml/dialogs/TabletAssetDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../styles-uit" import "../windows" diff --git a/interface/resources/qml/dialogs/TabletConnectionFailureDialog.qml b/interface/resources/qml/dialogs/TabletConnectionFailureDialog.qml index 6d2ff36550..544824135e 100644 --- a/interface/resources/qml/dialogs/TabletConnectionFailureDialog.qml +++ b/interface/resources/qml/dialogs/TabletConnectionFailureDialog.qml @@ -10,7 +10,6 @@ import Hifi 1.0 import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtQuick.Dialogs 1.2 as OriginalDialogs Item { diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index 269788a808..c85b2b2ba0 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -10,7 +10,6 @@ import Hifi 1.0 import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../controls-uit" import "../styles-uit" diff --git a/interface/resources/qml/dialogs/TabletMessageBox.qml b/interface/resources/qml/dialogs/TabletMessageBox.qml index f8876b1ec8..fabe0dd247 100644 --- a/interface/resources/qml/dialogs/TabletMessageBox.qml +++ b/interface/resources/qml/dialogs/TabletMessageBox.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtQuick.Dialogs 1.2 as OriginalDialogs import "../controls-uit" diff --git a/interface/resources/qml/dialogs/messageDialog/MessageDialogButton.qml b/interface/resources/qml/dialogs/messageDialog/MessageDialogButton.qml index b7ff9354eb..4a4d741619 100644 --- a/interface/resources/qml/dialogs/messageDialog/MessageDialogButton.qml +++ b/interface/resources/qml/dialogs/messageDialog/MessageDialogButton.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.2 import QtQuick.Dialogs 1.2 import "../../controls-uit" diff --git a/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml b/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml index 5949adffca..d03fc4d880 100644 --- a/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml +++ b/interface/resources/qml/dialogs/preferences/AvatarBrowser.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtWebChannel 1.0 import QtWebEngine 1.2 diff --git a/interface/resources/qml/dialogs/preferences/ComboBoxPreference.qml b/interface/resources/qml/dialogs/preferences/ComboBoxPreference.qml index 860cbcb5a8..3b3efaf520 100644 --- a/interface/resources/qml/dialogs/preferences/ComboBoxPreference.qml +++ b/interface/resources/qml/dialogs/preferences/ComboBoxPreference.qml @@ -10,8 +10,6 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "../../controls-uit" as HiFiControls import "../../styles-uit" diff --git a/interface/resources/qml/dialogs/preferences/Preference.qml b/interface/resources/qml/dialogs/preferences/Preference.qml index 1d72197382..6956147950 100644 --- a/interface/resources/qml/dialogs/preferences/Preference.qml +++ b/interface/resources/qml/dialogs/preferences/Preference.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 Item { id: root diff --git a/interface/resources/qml/hifi/ComboDialog.qml b/interface/resources/qml/hifi/ComboDialog.qml index 83fcad18c7..a0cee109a8 100644 --- a/interface/resources/qml/hifi/ComboDialog.qml +++ b/interface/resources/qml/hifi/ComboDialog.qml @@ -10,7 +10,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../styles-uit" import "../controls-uit" diff --git a/interface/resources/qml/hifi/DesktopLetterboxMessage.qml b/interface/resources/qml/hifi/DesktopLetterboxMessage.qml index bafa518eb9..1804177fd7 100644 --- a/interface/resources/qml/hifi/DesktopLetterboxMessage.qml +++ b/interface/resources/qml/hifi/DesktopLetterboxMessage.qml @@ -10,7 +10,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../styles-uit" Item { diff --git a/interface/resources/qml/hifi/LetterboxMessage.qml b/interface/resources/qml/hifi/LetterboxMessage.qml index 7ce66adf11..d5b5dc9d5e 100644 --- a/interface/resources/qml/hifi/LetterboxMessage.qml +++ b/interface/resources/qml/hifi/LetterboxMessage.qml @@ -10,7 +10,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../styles-uit" Item { diff --git a/interface/resources/qml/hifi/audio/InputPeak.qml b/interface/resources/qml/hifi/audio/InputPeak.qml index 4ff49091b1..ca65bc699e 100644 --- a/interface/resources/qml/hifi/audio/InputPeak.qml +++ b/interface/resources/qml/hifi/audio/InputPeak.qml @@ -10,8 +10,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 Rectangle { diff --git a/interface/resources/qml/hifi/audio/MicBar.qml b/interface/resources/qml/hifi/audio/MicBar.qml index b6699d6ceb..0d6f938e5d 100644 --- a/interface/resources/qml/hifi/audio/MicBar.qml +++ b/interface/resources/qml/hifi/audio/MicBar.qml @@ -10,8 +10,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import TabletScriptingInterface 1.0 diff --git a/interface/resources/qml/hifi/commerce/common/CommerceLightbox.qml b/interface/resources/qml/hifi/commerce/common/CommerceLightbox.qml index 145b78bdc4..1dde0373c8 100644 --- a/interface/resources/qml/hifi/commerce/common/CommerceLightbox.qml +++ b/interface/resources/qml/hifi/commerce/common/CommerceLightbox.qml @@ -14,7 +14,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml index 8b3f017fd2..e8559b3019 100644 --- a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml +++ b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml @@ -14,7 +14,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.7 import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml b/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml index 0d3f67ef7a..0f9db0a51e 100644 --- a/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml +++ b/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml @@ -14,7 +14,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml index b6c29a1fad..47aacc80a3 100644 --- a/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml +++ b/interface/resources/qml/hifi/commerce/inspectionCertificate/InspectionCertificate.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index f292f9603e..767cae82a5 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml b/interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml index 7ce0cf3853..ae95b3d80a 100644 --- a/interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml +++ b/interface/resources/qml/hifi/commerce/wallet/NeedsLogIn.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseChange.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseChange.qml index a75d511793..8adb78cc53 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseChange.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseChange.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index d967a36b68..3eed3f7bf9 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml index ffeedde8f0..b132e76d67 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/Security.qml b/interface/resources/qml/hifi/commerce/wallet/Security.qml index 485b0ec086..d5696c2c56 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Security.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Security.qml @@ -14,7 +14,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/SecurityImageChange.qml b/interface/resources/qml/hifi/commerce/wallet/SecurityImageChange.qml index 7f767060f6..cc644ed457 100644 --- a/interface/resources/qml/hifi/commerce/wallet/SecurityImageChange.qml +++ b/interface/resources/qml/hifi/commerce/wallet/SecurityImageChange.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/SecurityImageSelection.qml b/interface/resources/qml/hifi/commerce/wallet/SecurityImageSelection.qml index e12332cd0c..548e4c1777 100644 --- a/interface/resources/qml/hifi/commerce/wallet/SecurityImageSelection.qml +++ b/interface/resources/qml/hifi/commerce/wallet/SecurityImageSelection.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml index 75334b1686..438d343230 100644 --- a/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/SendMoney.qml @@ -13,7 +13,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 759d7a37eb..aa032d9ebd 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -14,7 +14,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml index 99fe933bd6..a54a2ba373 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml @@ -14,7 +14,6 @@ import Hifi 1.0 as Hifi import QtQuick 2.5 import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControlsUit import "../../../controls" as HifiControls diff --git a/interface/resources/qml/hifi/dialogs/AttachmentsDialog.qml b/interface/resources/qml/hifi/dialogs/AttachmentsDialog.qml index 76484cf8c7..006a4b7158 100644 --- a/interface/resources/qml/hifi/dialogs/AttachmentsDialog.qml +++ b/interface/resources/qml/hifi/dialogs/AttachmentsDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import Qt.labs.settings 1.0 import "../../styles-uit" diff --git a/interface/resources/qml/hifi/dialogs/ModelBrowserDialog.qml b/interface/resources/qml/hifi/dialogs/ModelBrowserDialog.qml index c427052904..55b4e98bf5 100644 --- a/interface/resources/qml/hifi/dialogs/ModelBrowserDialog.qml +++ b/interface/resources/qml/hifi/dialogs/ModelBrowserDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../windows" import "content" diff --git a/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml b/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml index 0f363d1be9..1ec7ea3e0e 100644 --- a/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml +++ b/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import Qt.labs.settings 1.0 import "../../styles-uit" diff --git a/interface/resources/qml/hifi/dialogs/TabletEntityStatistics.qml b/interface/resources/qml/hifi/dialogs/TabletEntityStatistics.qml index da295917a0..7bce460283 100644 --- a/interface/resources/qml/hifi/dialogs/TabletEntityStatistics.qml +++ b/interface/resources/qml/hifi/dialogs/TabletEntityStatistics.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import Qt.labs.settings 1.0 import "../../styles-uit" diff --git a/interface/resources/qml/hifi/dialogs/TabletEntityStatisticsItem.qml b/interface/resources/qml/hifi/dialogs/TabletEntityStatisticsItem.qml index 894a4c1813..d5c5a5ee02 100644 --- a/interface/resources/qml/hifi/dialogs/TabletEntityStatisticsItem.qml +++ b/interface/resources/qml/hifi/dialogs/TabletEntityStatisticsItem.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import Qt.labs.settings 1.0 import "../../styles-uit" import "../../controls-uit" as HifiControls diff --git a/interface/resources/qml/hifi/dialogs/TabletLODTools.qml b/interface/resources/qml/hifi/dialogs/TabletLODTools.qml index 2291a42bf6..ab53f03477 100644 --- a/interface/resources/qml/hifi/dialogs/TabletLODTools.qml +++ b/interface/resources/qml/hifi/dialogs/TabletLODTools.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import Qt.labs.settings 1.0 import "../../styles-uit" import "../../controls-uit" as HifiControls diff --git a/interface/resources/qml/hifi/dialogs/attachments/Attachment.qml b/interface/resources/qml/hifi/dialogs/attachments/Attachment.qml index b6f906ffc2..89ad327a71 100644 --- a/interface/resources/qml/hifi/dialogs/attachments/Attachment.qml +++ b/interface/resources/qml/hifi/dialogs/attachments/Attachment.qml @@ -1,8 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import QtQuick.Dialogs 1.2 as OriginalDialogs -import Qt.labs.settings 1.0 import "." import ".." diff --git a/interface/resources/qml/hifi/dialogs/attachments/Vector3.qml b/interface/resources/qml/hifi/dialogs/attachments/Vector3.qml index 29f2c0ebf4..eb6172ec78 100644 --- a/interface/resources/qml/hifi/dialogs/attachments/Vector3.qml +++ b/interface/resources/qml/hifi/dialogs/attachments/Vector3.qml @@ -1,5 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControls diff --git a/interface/resources/qml/hifi/overlays/ImageOverlay.qml b/interface/resources/qml/hifi/overlays/ImageOverlay.qml index b509f0ce3a..b111596db7 100644 --- a/interface/resources/qml/hifi/overlays/ImageOverlay.qml +++ b/interface/resources/qml/hifi/overlays/ImageOverlay.qml @@ -1,5 +1,4 @@ import QtQuick 2.3 -import QtQuick.Controls 1.2 import QtGraphicalEffects 1.0 import "." diff --git a/interface/resources/qml/hifi/overlays/Overlay.qml b/interface/resources/qml/hifi/overlays/Overlay.qml index 80f3233b69..188833bf88 100644 --- a/interface/resources/qml/hifi/overlays/Overlay.qml +++ b/interface/resources/qml/hifi/overlays/Overlay.qml @@ -1,6 +1,5 @@ import Hifi 1.0 import QtQuick 2.3 -import QtQuick.Controls 1.2 Item { id: root diff --git a/interface/resources/qml/hifi/overlays/RectangleOverlay.qml b/interface/resources/qml/hifi/overlays/RectangleOverlay.qml index cba3b560d2..4d33d73f85 100644 --- a/interface/resources/qml/hifi/overlays/RectangleOverlay.qml +++ b/interface/resources/qml/hifi/overlays/RectangleOverlay.qml @@ -1,5 +1,4 @@ import QtQuick 2.3 -import QtQuick.Controls 1.2 import "." diff --git a/interface/resources/qml/hifi/overlays/TextOverlay.qml b/interface/resources/qml/hifi/overlays/TextOverlay.qml index 20336fdde6..a162fc01f5 100644 --- a/interface/resources/qml/hifi/overlays/TextOverlay.qml +++ b/interface/resources/qml/hifi/overlays/TextOverlay.qml @@ -1,5 +1,4 @@ import QtQuick 2.3 -import QtQuick.Controls 1.2 import "." diff --git a/interface/resources/qml/hifi/tablet/CalibratingScreen.qml b/interface/resources/qml/hifi/tablet/CalibratingScreen.qml index dd56bc96ab..6c26bd87c5 100644 --- a/interface/resources/qml/hifi/tablet/CalibratingScreen.qml +++ b/interface/resources/qml/hifi/tablet/CalibratingScreen.qml @@ -8,11 +8,8 @@ import QtQuick 2.5 - -import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtGraphicalEffects 1.0 -import QtQuick.Controls.Styles 1.4 + import "../../styles-uit" import "../../controls" import "../../controls-uit" as HifiControls diff --git a/interface/resources/qml/hifi/tablet/InputRecorder.qml b/interface/resources/qml/hifi/tablet/InputRecorder.qml index 292deb751e..527a6cacb4 100644 --- a/interface/resources/qml/hifi/tablet/InputRecorder.qml +++ b/interface/resources/qml/hifi/tablet/InputRecorder.qml @@ -8,8 +8,6 @@ import QtQuick 2.5 import Hifi 1.0 -import QtQuick.Controls 1.4 -import QtQuick.Dialogs 1.2 as OriginalDialogs import "../../styles-uit" import "../../controls-uit" as HifiControls diff --git a/interface/resources/qml/hifi/tablet/NewModelDialog.qml b/interface/resources/qml/hifi/tablet/NewModelDialog.qml index 47d28486a9..be0e5fc77a 100644 --- a/interface/resources/qml/hifi/tablet/NewModelDialog.qml +++ b/interface/resources/qml/hifi/tablet/NewModelDialog.qml @@ -10,7 +10,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../styles-uit" import "../../controls-uit" diff --git a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml index 78c10e2ffa..25abbb994a 100644 --- a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml +++ b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml @@ -7,10 +7,8 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtGraphicalEffects 1.0 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 + import "../../styles-uit" import "../../controls" import "../../controls-uit" as HifiControls @@ -53,10 +51,6 @@ Rectangle { } - - - - MouseArea { id: mouseArea @@ -593,9 +587,6 @@ Rectangle { } } - - - HiFiGlyphs { id: glyphButton color: enabled ? hifi.buttons.textColor[calibrationButton.color] @@ -625,7 +616,6 @@ Rectangle { } } - MouseArea { anchors.fill: parent hoverEnabled: true diff --git a/interface/resources/qml/hifi/tablet/TabletAttachmentsDialog.qml b/interface/resources/qml/hifi/tablet/TabletAttachmentsDialog.qml index 19548365aa..7e1cdea0db 100644 --- a/interface/resources/qml/hifi/tablet/TabletAttachmentsDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAttachmentsDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../controls-uit" as HifiControls import "../../styles-uit" diff --git a/interface/resources/qml/hifi/tablet/TabletMenuItem.qml b/interface/resources/qml/hifi/tablet/TabletMenuItem.qml index 11d3cab35e..5612e4d629 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuItem.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuItem.qml @@ -10,7 +10,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "../../controls-uit" import "../../styles-uit" diff --git a/interface/resources/qml/hifi/tablet/TabletMenuView.qml b/interface/resources/qml/hifi/tablet/TabletMenuView.qml index 4a4a6b7f87..67eeb5b010 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuView.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuView.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import TabletScriptingInterface 1.0 import "../../styles-uit" diff --git a/interface/resources/qml/hifi/tablet/TabletModelBrowserDialog.qml b/interface/resources/qml/hifi/tablet/TabletModelBrowserDialog.qml index 60bd7a88e0..d69d760b95 100644 --- a/interface/resources/qml/hifi/tablet/TabletModelBrowserDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletModelBrowserDialog.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../controls-uit" as HifiControls import "../../styles-uit" diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index a161741049..0d2ea6bda0 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -1,6 +1,5 @@ import QtQuick 2.0 import Hifi 1.0 -import QtQuick.Controls 1.4 import "../../dialogs" import "../../controls" diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml index fcb3e9ff92..a5ef3d2686 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml @@ -9,10 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import QtGraphicalEffects 1.0 - import "." import "./preferences" diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Preference.qml b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Preference.qml index 9986c85445..fcf022c8ef 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Preference.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Preference.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 Item { id: root diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Section.qml b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Section.qml index 8cf254809d..5036569031 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Section.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/Section.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import Hifi 1.0 import "../../../../dialogs/preferences" diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/TabletAvatarBrowser.qml b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/TabletAvatarBrowser.qml index 2ea12f1d3d..25b08b2b5a 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/preferences/TabletAvatarBrowser.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/preferences/TabletAvatarBrowser.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 import QtWebChannel 1.0 import QtWebEngine 1.2 diff --git a/interface/resources/qml/hifi/toolbars/StateImage.qml b/interface/resources/qml/hifi/toolbars/StateImage.qml index ebf1544f2b..9cd311060d 100644 --- a/interface/resources/qml/hifi/toolbars/StateImage.qml +++ b/interface/resources/qml/hifi/toolbars/StateImage.qml @@ -1,5 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 Item { property alias imageURL: image.source diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml index 01aa29f665..c3477baaaa 100644 --- a/interface/resources/qml/hifi/toolbars/Toolbar.qml +++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml @@ -1,5 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 import Qt.labs.settings 1.0 import "../../windows" diff --git a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml index 63149ad23b..14a3537332 100644 --- a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml +++ b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml @@ -1,5 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 StateImage { id: button diff --git a/interface/resources/qml/styles-uit/AnonymousProRegular.qml b/interface/resources/qml/styles-uit/AnonymousProRegular.qml index 789689973b..83e1de8d02 100644 --- a/interface/resources/qml/styles-uit/AnonymousProRegular.qml +++ b/interface/resources/qml/styles-uit/AnonymousProRegular.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 Text { id: root diff --git a/interface/resources/qml/styles-uit/ButtonLabel.qml b/interface/resources/qml/styles-uit/ButtonLabel.qml index aade5fb439..d227cb4869 100644 --- a/interface/resources/qml/styles-uit/ButtonLabel.qml +++ b/interface/resources/qml/styles-uit/ButtonLabel.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewayBold { diff --git a/interface/resources/qml/styles-uit/FiraSansRegular.qml b/interface/resources/qml/styles-uit/FiraSansRegular.qml index 4ae0826772..3413361de1 100644 --- a/interface/resources/qml/styles-uit/FiraSansRegular.qml +++ b/interface/resources/qml/styles-uit/FiraSansRegular.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 Text { id: root diff --git a/interface/resources/qml/styles-uit/FiraSansSemiBold.qml b/interface/resources/qml/styles-uit/FiraSansSemiBold.qml index b3f3324090..1ac7048bc0 100644 --- a/interface/resources/qml/styles-uit/FiraSansSemiBold.qml +++ b/interface/resources/qml/styles-uit/FiraSansSemiBold.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 Text { id: root diff --git a/interface/resources/qml/styles-uit/IconButton.qml b/interface/resources/qml/styles-uit/IconButton.qml index 84c1ef14c1..e5a18e2ae7 100644 --- a/interface/resources/qml/styles-uit/IconButton.qml +++ b/interface/resources/qml/styles-uit/IconButton.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewayRegular { diff --git a/interface/resources/qml/styles-uit/InfoItem.qml b/interface/resources/qml/styles-uit/InfoItem.qml index 83781a4ef5..fa7684e8e7 100644 --- a/interface/resources/qml/styles-uit/InfoItem.qml +++ b/interface/resources/qml/styles-uit/InfoItem.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewaySemiBold { diff --git a/interface/resources/qml/styles-uit/InputLabel.qml b/interface/resources/qml/styles-uit/InputLabel.qml index 59657a554d..3853dd5b19 100644 --- a/interface/resources/qml/styles-uit/InputLabel.qml +++ b/interface/resources/qml/styles-uit/InputLabel.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewaySemiBold { diff --git a/interface/resources/qml/styles-uit/ListItem.qml b/interface/resources/qml/styles-uit/ListItem.qml index f707686edc..a69c4b48c2 100644 --- a/interface/resources/qml/styles-uit/ListItem.qml +++ b/interface/resources/qml/styles-uit/ListItem.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewayRegular { diff --git a/interface/resources/qml/styles-uit/Logs.qml b/interface/resources/qml/styles-uit/Logs.qml index 577fe2f8d8..45d4436fbf 100644 --- a/interface/resources/qml/styles-uit/Logs.qml +++ b/interface/resources/qml/styles-uit/Logs.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." AnonymousProRegular { diff --git a/interface/resources/qml/styles-uit/OverlayTitle.qml b/interface/resources/qml/styles-uit/OverlayTitle.qml index e23b9eca14..0fb423baab 100644 --- a/interface/resources/qml/styles-uit/OverlayTitle.qml +++ b/interface/resources/qml/styles-uit/OverlayTitle.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewayRegular { diff --git a/interface/resources/qml/styles-uit/RalewayBold.qml b/interface/resources/qml/styles-uit/RalewayBold.qml index 433fdb7ae6..2d529cff8a 100644 --- a/interface/resources/qml/styles-uit/RalewayBold.qml +++ b/interface/resources/qml/styles-uit/RalewayBold.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 Text { id: root diff --git a/interface/resources/qml/styles-uit/RalewayLight.qml b/interface/resources/qml/styles-uit/RalewayLight.qml index 913918afd7..7785bc29d0 100644 --- a/interface/resources/qml/styles-uit/RalewayLight.qml +++ b/interface/resources/qml/styles-uit/RalewayLight.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 Text { id: root diff --git a/interface/resources/qml/styles-uit/RalewayRegular.qml b/interface/resources/qml/styles-uit/RalewayRegular.qml index aab31ecf33..2b1c17e49c 100644 --- a/interface/resources/qml/styles-uit/RalewayRegular.qml +++ b/interface/resources/qml/styles-uit/RalewayRegular.qml @@ -9,8 +9,6 @@ // import QtQuick 2.7 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 Text { id: root diff --git a/interface/resources/qml/styles-uit/RalewaySemiBold.qml b/interface/resources/qml/styles-uit/RalewaySemiBold.qml index b6c79e02a4..fe3a42dd6c 100644 --- a/interface/resources/qml/styles-uit/RalewaySemiBold.qml +++ b/interface/resources/qml/styles-uit/RalewaySemiBold.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 Text { id: root diff --git a/interface/resources/qml/styles-uit/SectionName.qml b/interface/resources/qml/styles-uit/SectionName.qml index 5438fec7bc..20f8e1e116 100644 --- a/interface/resources/qml/styles-uit/SectionName.qml +++ b/interface/resources/qml/styles-uit/SectionName.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewayRegular { diff --git a/interface/resources/qml/styles-uit/ShortcutText.qml b/interface/resources/qml/styles-uit/ShortcutText.qml index a3ab351870..8504ffa2b8 100644 --- a/interface/resources/qml/styles-uit/ShortcutText.qml +++ b/interface/resources/qml/styles-uit/ShortcutText.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewayLight { diff --git a/interface/resources/qml/styles-uit/TabName.qml b/interface/resources/qml/styles-uit/TabName.qml index eb4e790e7e..0f620fe8c2 100644 --- a/interface/resources/qml/styles-uit/TabName.qml +++ b/interface/resources/qml/styles-uit/TabName.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." RalewayRegular { diff --git a/interface/resources/qml/styles-uit/TextFieldInput.qml b/interface/resources/qml/styles-uit/TextFieldInput.qml index 010b4d03ad..f2a57e57fc 100644 --- a/interface/resources/qml/styles-uit/TextFieldInput.qml +++ b/interface/resources/qml/styles-uit/TextFieldInput.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import "." FiraSansSemiBold { diff --git a/interface/resources/qml/windows/DefaultFrame.qml b/interface/resources/qml/windows/DefaultFrame.qml index 33c2818849..60e744bec3 100644 --- a/interface/resources/qml/windows/DefaultFrame.qml +++ b/interface/resources/qml/windows/DefaultFrame.qml @@ -9,7 +9,6 @@ // import QtQuick 2.5 -import QtGraphicalEffects 1.0 import "." import "../styles-uit" diff --git a/interface/resources/qml/windows/Fadable.qml b/interface/resources/qml/windows/Fadable.qml index 4d506755f2..0945c6e47e 100644 --- a/interface/resources/qml/windows/Fadable.qml +++ b/interface/resources/qml/windows/Fadable.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtGraphicalEffects 1.0 import "../styles-uit" diff --git a/interface/resources/qml/windows/TabletModalWindow.qml b/interface/resources/qml/windows/TabletModalWindow.qml index e21cb6b224..0dbf4689d6 100644 --- a/interface/resources/qml/windows/TabletModalWindow.qml +++ b/interface/resources/qml/windows/TabletModalWindow.qml @@ -8,9 +8,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Dialogs 1.2 as OriginalDialogs -import "." Rectangle { id: modalWindow diff --git a/interface/resources/qml/windows/Window.qml b/interface/resources/qml/windows/Window.qml index a0ef73290a..ea68fd8783 100644 --- a/interface/resources/qml/windows/Window.qml +++ b/interface/resources/qml/windows/Window.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import QtGraphicalEffects 1.0 import "." From 6b732804eb279ed720013c7fdd82e9c9000695c5 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 13 Nov 2017 21:15:31 +0100 Subject: [PATCH 002/109] Button as QQC2 --- .../resources/qml/controls-uit/Button.qml | 140 +++++++++--------- interface/resources/qml/controls/Button.qml | 35 ++--- 2 files changed, 86 insertions(+), 89 deletions(-) diff --git a/interface/resources/qml/controls-uit/Button.qml b/interface/resources/qml/controls-uit/Button.qml index c068fdcfaf..c6bac84510 100644 --- a/interface/resources/qml/controls-uit/Button.qml +++ b/interface/resources/qml/controls-uit/Button.qml @@ -9,19 +9,21 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.2 as Original import TabletScriptingInterface 1.0 import "../styles-uit" Original.Button { - id: root; + id: control; property int color: 0 property int colorScheme: hifi.colorSchemes.light property string buttonGlyph: ""; + //TODO: add real Action item. Backport from Qt 5.10 + property QtObject action: null + width: 120 height: hifi.dimensions.controlLineHeight @@ -37,79 +39,77 @@ Original.Button { tabletInterface.playSound(TabletEnums.ButtonClick); } - style: ButtonStyle { + background: Rectangle { + radius: hifi.buttons.radius - background: Rectangle { - radius: hifi.buttons.radius + border.width: (control.color === hifi.buttons.none || + (control.color === hifi.buttons.noneBorderless && control.hovered) || + (control.color === hifi.buttons.noneBorderlessWhite && control.hovered) || + (control.color === hifi.buttons.noneBorderlessGray && control.hovered)) ? 1 : 0; + border.color: control.color === hifi.buttons.noneBorderless ? hifi.colors.blueHighlight : + (control.color === hifi.buttons.noneBorderlessGray ? hifi.colors.baseGray : hifi.colors.white); - border.width: (control.color === hifi.buttons.none || - (control.color === hifi.buttons.noneBorderless && control.hovered) || - (control.color === hifi.buttons.noneBorderlessWhite && control.hovered) || - (control.color === hifi.buttons.noneBorderlessGray && control.hovered)) ? 1 : 0; - border.color: control.color === hifi.buttons.noneBorderless ? hifi.colors.blueHighlight : - (control.color === hifi.buttons.noneBorderlessGray ? hifi.colors.baseGray : hifi.colors.white); - - gradient: Gradient { - GradientStop { - position: 0.2 - color: { - if (!control.enabled) { - hifi.buttons.disabledColorStart[control.colorScheme] - } else if (control.pressed) { - hifi.buttons.pressedColor[control.color] - } else if (control.hovered) { - hifi.buttons.hoveredColor[control.color] - } else { - hifi.buttons.colorStart[control.color] - } - } - } - GradientStop { - position: 1.0 - color: { - if (!control.enabled) { - hifi.buttons.disabledColorFinish[control.colorScheme] - } else if (control.pressed) { - hifi.buttons.pressedColor[control.color] - } else if (control.hovered) { - hifi.buttons.hoveredColor[control.color] - } else { - hifi.buttons.colorFinish[control.color] - } + gradient: Gradient { + GradientStop { + position: 0.2 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorStart[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else { + hifi.buttons.colorStart[control.color] } } } - } - - label: Item { - HiFiGlyphs { - id: buttonGlyph; - visible: root.buttonGlyph !== ""; - text: root.buttonGlyph === "" ? hifi.glyphs.question : root.buttonGlyph; - // Size - size: 34; - // Anchors - anchors.right: buttonText.left; - anchors.top: parent.top; - anchors.bottom: parent.bottom; - // Style - color: enabled ? hifi.buttons.textColor[control.color] - : hifi.buttons.disabledTextColor[control.colorScheme]; - // Alignment - horizontalAlignment: Text.AlignHCenter; - verticalAlignment: Text.AlignVCenter; - } - RalewayBold { - id: buttonText; - anchors.centerIn: parent; - font.capitalization: Font.AllUppercase - color: enabled ? hifi.buttons.textColor[control.color] - : hifi.buttons.disabledTextColor[control.colorScheme] - size: hifi.fontSizes.buttonLabel - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - text: control.text + GradientStop { + position: 1.0 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorFinish[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else { + hifi.buttons.colorFinish[control.color] + } + } } } } + + contentItem: Item { + HiFiGlyphs { + id: buttonGlyph; + visible: control.buttonGlyph !== ""; + text: control.buttonGlyph === "" ? hifi.glyphs.question : control.buttonGlyph; + // Size + size: 34; + // Anchors + anchors.right: buttonText.left; + anchors.top: parent.top; + anchors.bottom: parent.bottom; + // Style + color: enabled ? hifi.buttons.textColor[control.color] + : hifi.buttons.disabledTextColor[control.colorScheme]; + // Alignment + horizontalAlignment: Text.AlignHCenter; + verticalAlignment: Text.AlignVCenter; + } + RalewayBold { + id: buttonText; + anchors.centerIn: parent; + font.capitalization: Font.AllUppercase + color: enabled ? hifi.buttons.textColor[control.color] + : hifi.buttons.disabledTextColor[control.colorScheme] + size: hifi.fontSizes.buttonLabel + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: control.text + } + } } + diff --git a/interface/resources/qml/controls/Button.qml b/interface/resources/qml/controls/Button.qml index c5a9f99343..ac3c2d32d4 100644 --- a/interface/resources/qml/controls/Button.qml +++ b/interface/resources/qml/controls/Button.qml @@ -1,27 +1,24 @@ import QtQuick 2.3 -import QtQuick.Controls 1.3 as Original -import QtQuick.Controls.Styles 1.3 +import QtQuick.Controls 2.2 as Original import "." import "../styles" Original.Button { - style: ButtonStyle { - HifiConstants { id: hifi } - padding { - top: 8 - left: 12 - right: 12 - bottom: 8 - } - background: Border { - anchors.fill: parent - } - label: Text { - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - text: control.text - color: control.enabled ? hifi.colors.text : hifi.colors.disabledText - } + HifiConstants { id: hifi } + padding { + top: 8 + left: 12 + right: 12 + bottom: 8 + } + background: Border { + anchors.fill: parent + } + contentItem: Text { + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: control.text + color: control.enabled ? hifi.colors.text : hifi.colors.disabledText } } From 28523752853e8bb1ae908bd42d4043410ecca19c Mon Sep 17 00:00:00 2001 From: vladest Date: Wed, 15 Nov 2017 20:32:28 +0100 Subject: [PATCH 003/109] Make QueryDioalogs buttons works --- .../resources/qml/controls-uit/Button.qml | 7 +++-- .../resources/qml/dialogs/QueryDialog.qml | 28 +++++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/interface/resources/qml/controls-uit/Button.qml b/interface/resources/qml/controls-uit/Button.qml index c6bac84510..165de98878 100644 --- a/interface/resources/qml/controls-uit/Button.qml +++ b/interface/resources/qml/controls-uit/Button.qml @@ -8,7 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 +import QtQuick 2.7 import QtQuick.Controls 2.2 as Original import TabletScriptingInterface 1.0 @@ -22,7 +22,7 @@ Original.Button { property string buttonGlyph: ""; //TODO: add real Action item. Backport from Qt 5.10 - property QtObject action: null + property Shortcut action: null width: 120 height: hifi.dimensions.controlLineHeight @@ -37,6 +37,9 @@ Original.Button { onClicked: { tabletInterface.playSound(TabletEnums.ButtonClick); + if (action !== null) { + action.activated() + } } background: Rectangle { diff --git a/interface/resources/qml/dialogs/QueryDialog.qml b/interface/resources/qml/dialogs/QueryDialog.qml index 9a38c3f0d6..159e5a1801 100644 --- a/interface/resources/qml/dialogs/QueryDialog.qml +++ b/interface/resources/qml/dialogs/QueryDialog.qml @@ -9,7 +9,7 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.2 import QtQuick.Dialogs 1.2 as OriginalDialogs import "../controls-uit" @@ -145,24 +145,30 @@ ModalWindow { margins: 0 bottomMargin: hifi.dimensions.contentSpacing.y } - Button { action: cancelAction } - Button { action: acceptAction } + Button { + action: cancelAction; + text: qsTr("Cancel"); + } + + Button { + action: acceptAction + text: qsTr("OK"); + } } - Action { + Shortcut { id: cancelAction - text: qsTr("Cancel") - shortcut: Qt.Key_Escape - onTriggered: { + sequence: Qt.Key_Escape + onActivated: { root.canceled(); root.destroy(); } } - Action { + + Shortcut { id: acceptAction - text: qsTr("OK") - shortcut: Qt.Key_Return - onTriggered: { + sequence: Qt.Key_Return + onActivated: { root.result = items ? comboBox.currentText : textResult.text root.selected(root.result); root.destroy(); From b4f6c25f4d21e77b670349abaf1c5c41bb0bb571 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 16 Nov 2017 19:04:35 +0100 Subject: [PATCH 004/109] Implement QQC1-compatible Action component --- .../resources/qml/controls-uit/Action.qml | 8 ++ .../resources/qml/controls-uit/Button.qml | 11 ++- .../qml/controls-uit/GlyphButton.qml | 94 ++++++++++--------- interface/resources/qml/controls/Button.qml | 11 +++ .../resources/qml/dialogs/FileDialog.qml | 11 +-- .../resources/qml/dialogs/QueryDialog.qml | 14 ++- .../qml/dialogs/TabletFileDialog.qml | 11 +-- 7 files changed, 91 insertions(+), 69 deletions(-) create mode 100644 interface/resources/qml/controls-uit/Action.qml diff --git a/interface/resources/qml/controls-uit/Action.qml b/interface/resources/qml/controls-uit/Action.qml new file mode 100644 index 0000000000..5dbfa3914b --- /dev/null +++ b/interface/resources/qml/controls-uit/Action.qml @@ -0,0 +1,8 @@ +import QtQuick 2.7 + +Shortcut { + id: root + property string text + property alias shortcut: root.sequence + signal triggered() +} diff --git a/interface/resources/qml/controls-uit/Button.qml b/interface/resources/qml/controls-uit/Button.qml index 165de98878..7d1607caa9 100644 --- a/interface/resources/qml/controls-uit/Button.qml +++ b/interface/resources/qml/controls-uit/Button.qml @@ -21,8 +21,7 @@ Original.Button { property int colorScheme: hifi.colorSchemes.light property string buttonGlyph: ""; - //TODO: add real Action item. Backport from Qt 5.10 - property Shortcut action: null + property Action action: null width: 120 height: hifi.dimensions.controlLineHeight @@ -35,10 +34,16 @@ Original.Button { } } + onActionChanged: { + if (action !== null && action.text !== "") { + control.text = action.text + } + } + onClicked: { tabletInterface.playSound(TabletEnums.ButtonClick); if (action !== null) { - action.activated() + action.triggered() } } diff --git a/interface/resources/qml/controls-uit/GlyphButton.qml b/interface/resources/qml/controls-uit/GlyphButton.qml index bc7bc636fe..2c715ea29c 100644 --- a/interface/resources/qml/controls-uit/GlyphButton.qml +++ b/interface/resources/qml/controls-uit/GlyphButton.qml @@ -8,15 +8,14 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 as Original import TabletScriptingInterface 1.0 import "../styles-uit" Original.Button { + id: control property int color: 0 property int colorScheme: hifi.colorSchemes.light property string glyph: "" @@ -25,65 +24,68 @@ Original.Button { width: 120 height: 28 + property Action action: null + onHoveredChanged: { if (hovered) { tabletInterface.playSound(TabletEnums.ButtonHover); } } + onActionChanged: { + if (action !== null && action.text !== "") { + control.text = action.text + } + } onClicked: { tabletInterface.playSound(TabletEnums.ButtonClick); + if (action !== null) { + action.triggered() + } } - style: ButtonStyle { + background: Rectangle { + radius: hifi.buttons.radius - background: Rectangle { - radius: hifi.buttons.radius - - gradient: Gradient { - GradientStop { - position: 0.2 - color: { - if (!control.enabled) { - hifi.buttons.disabledColorStart[control.colorScheme] - } else if (control.pressed) { - hifi.buttons.pressedColor[control.color] - } else if (control.hovered) { - hifi.buttons.hoveredColor[control.color] - } else { - hifi.buttons.colorStart[control.color] - } + gradient: Gradient { + GradientStop { + position: 0.2 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorStart[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else { + hifi.buttons.colorStart[control.color] } } - GradientStop { - position: 1.0 - color: { - if (!control.enabled) { - hifi.buttons.disabledColorFinish[control.colorScheme] - } else if (control.pressed) { - hifi.buttons.pressedColor[control.color] - } else if (control.hovered) { - hifi.buttons.hoveredColor[control.color] - } else { - hifi.buttons.colorFinish[control.color] - } + } + GradientStop { + position: 1.0 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorFinish[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else { + hifi.buttons.colorFinish[control.color] } } } } + } - label: HiFiGlyphs { - color: enabled ? hifi.buttons.textColor[control.color] - : hifi.buttons.disabledTextColor[control.colorScheme] - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - anchors { - // Tweak horizontal alignment so that it looks right. - left: parent.left - leftMargin: -0.5 - } - text: control.glyph - size: control.size - } + contentItem: HiFiGlyphs { + color: enabled ? hifi.buttons.textColor[control.color] + : hifi.buttons.disabledTextColor[control.colorScheme] + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: control.glyph + size: control.size } } + diff --git a/interface/resources/qml/controls/Button.qml b/interface/resources/qml/controls/Button.qml index ac3c2d32d4..6cbdec5644 100644 --- a/interface/resources/qml/controls/Button.qml +++ b/interface/resources/qml/controls/Button.qml @@ -3,9 +3,20 @@ import QtQuick.Controls 2.2 as Original import "." import "../styles" +import "../controls-uit" Original.Button { + id: control + HifiConstants { id: hifi } + property Action action: null + + onActionChanged: { + if (action !== null && action.text !== "") { + control.text = action.text + } + } + padding { top: 8 left: 12 diff --git a/interface/resources/qml/dialogs/FileDialog.qml b/interface/resources/qml/dialogs/FileDialog.qml index b9633104d5..26530bf633 100644 --- a/interface/resources/qml/dialogs/FileDialog.qml +++ b/interface/resources/qml/dialogs/FileDialog.qml @@ -8,12 +8,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 import Qt.labs.folderlistmodel 2.1 import Qt.labs.settings 1.0 -import QtQuick.Controls.Styles 1.4 import QtQuick.Dialogs 1.2 as OriginalDialogs +import QtQuick.Controls 1.4 as QQC1 import ".." import "../controls-uit" @@ -543,7 +542,7 @@ ModalWindow { } } - TableViewColumn { + QQC1.TableViewColumn { id: fileNameColumn role: "fileName" title: "Name" @@ -551,7 +550,7 @@ ModalWindow { movable: false resizable: true } - TableViewColumn { + QQC1.TableViewColumn { id: fileMofifiedColumn role: "fileModified" title: "Date" @@ -560,7 +559,7 @@ ModalWindow { resizable: true visible: !selectDirectory } - TableViewColumn { + QQC1.TableViewColumn { role: "fileSize" title: "Size" width: fileTableView.width - fileNameColumn.width - fileMofifiedColumn.width diff --git a/interface/resources/qml/dialogs/QueryDialog.qml b/interface/resources/qml/dialogs/QueryDialog.qml index 159e5a1801..889bcda768 100644 --- a/interface/resources/qml/dialogs/QueryDialog.qml +++ b/interface/resources/qml/dialogs/QueryDialog.qml @@ -9,8 +9,6 @@ // import QtQuick 2.5 -import QtQuick.Controls 2.2 -import QtQuick.Dialogs 1.2 as OriginalDialogs import "../controls-uit" import "../styles-uit" @@ -147,28 +145,28 @@ ModalWindow { } Button { action: cancelAction; - text: qsTr("Cancel"); } Button { action: acceptAction - text: qsTr("OK"); } } - Shortcut { + Action { id: cancelAction + text: qsTr("Cancel"); sequence: Qt.Key_Escape - onActivated: { + onTriggered: { root.canceled(); root.destroy(); } } - Shortcut { + Action { id: acceptAction + text: qsTr("OK"); sequence: Qt.Key_Return - onActivated: { + onTriggered: { root.result = items ? comboBox.currentText : textResult.text root.selected(root.result); root.destroy(); diff --git a/interface/resources/qml/dialogs/TabletFileDialog.qml b/interface/resources/qml/dialogs/TabletFileDialog.qml index d3b738469e..a03e0d02f3 100644 --- a/interface/resources/qml/dialogs/TabletFileDialog.qml +++ b/interface/resources/qml/dialogs/TabletFileDialog.qml @@ -8,12 +8,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 import Qt.labs.folderlistmodel 2.1 import Qt.labs.settings 1.0 -import QtQuick.Controls.Styles 1.4 import QtQuick.Dialogs 1.2 as OriginalDialogs +import QtQuick.Controls 1.4 as QQC1 import ".." import "../controls-uit" @@ -541,7 +540,7 @@ TabletModalWindow { } } - TableViewColumn { + QQC1.TableViewColumn { id: fileNameColumn role: "fileName" title: "Name" @@ -549,7 +548,7 @@ TabletModalWindow { movable: false resizable: true } - TableViewColumn { + QQC1.TableViewColumn { id: fileMofifiedColumn role: "fileModified" title: "Date" @@ -558,7 +557,7 @@ TabletModalWindow { resizable: true visible: !selectDirectory } - TableViewColumn { + QQC1.TableViewColumn { role: "fileSize" title: "Size" width: fileTableView.width - fileNameColumn.width - fileMofifiedColumn.width From cfacf3b47dacbf446ecf6aed47f51ff8e96eed59 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 16 Nov 2017 21:58:09 +0100 Subject: [PATCH 005/109] Port web glyph button to QQC2 --- .../qml/controls-uit/WebGlyphButton.qml | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/interface/resources/qml/controls-uit/WebGlyphButton.qml b/interface/resources/qml/controls-uit/WebGlyphButton.qml index 15524e4188..fd7cd001b2 100644 --- a/interface/resources/qml/controls-uit/WebGlyphButton.qml +++ b/interface/resources/qml/controls-uit/WebGlyphButton.qml @@ -9,8 +9,7 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.2 as Original import "../styles-uit" @@ -26,23 +25,16 @@ Original.Button { readonly property color clickedColor: "#FFFFFF" readonly property color disabledColor: "#575757" - style: ButtonStyle { - background: Item {} + background: Item {} - - label: HiFiGlyphs { - color: control.enabled ? (control.pressed ? control.clickedColor : - (control.hovered ? control.hoverColor : control.normalColor)) : - control.disabledColor - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - anchors { - // Tweak horizontal alignment so that it looks right. - left: parent.left - leftMargin: -0.5 - } - text: control.glyph - size: control.size - } + contentItem: HiFiGlyphs { + color: control.enabled ? (control.pressed ? control.clickedColor : + (control.hovered ? control.hoverColor : control.normalColor)) : + control.disabledColor + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: control.glyph + size: control.size } } + From dbd6ec0dff5f64abd18f2fa02f74c01bad49e9d6 Mon Sep 17 00:00:00 2001 From: vladest Date: Fri, 17 Nov 2017 20:46:21 +0100 Subject: [PATCH 006/109] Port Edit.qml to QQC2 as well as some tablet preferences compinents --- .../qml/dialogs/CustomQueryDialog.qml | 3 +- .../qml/dialogs/TabletCustomQueryDialog.qml | 3 +- .../qml/dialogs/TabletQueryDialog.qml | 3 +- .../assetDialog/AssetDialogContent.qml | 2 +- interface/resources/qml/hifi/Desktop.qml | 6 +- .../resources/qml/hifi/SpectatorCamera.qml | 3 +- interface/resources/qml/hifi/tablet/Edit.qml | 292 +++++++++++++++++- .../qml/hifi/tablet/EditTabButton.qml | 52 ++++ .../qml/hifi/tablet/TabletAddressDialog.qml | 4 +- .../qml/hifi/tablet/TabletAudioBuffers.qml | 4 +- .../hifi/tablet/TabletGeneralPreferences.qml | 4 +- .../hifi/tablet/TabletGraphicsPreferences.qml | 4 +- .../qml/hifi/tablet/TabletLodPreferences.qml | 4 +- .../tablet/TabletNetworkingPreferences.qml | 4 +- 14 files changed, 351 insertions(+), 37 deletions(-) create mode 100644 interface/resources/qml/hifi/tablet/EditTabButton.qml diff --git a/interface/resources/qml/dialogs/CustomQueryDialog.qml b/interface/resources/qml/dialogs/CustomQueryDialog.qml index 4d6fe74bca..403cd526ce 100644 --- a/interface/resources/qml/dialogs/CustomQueryDialog.qml +++ b/interface/resources/qml/dialogs/CustomQueryDialog.qml @@ -8,8 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5; -import QtQuick.Controls 1.4; +import QtQuick 2.7; import QtQuick.Dialogs 1.2 as OriginalDialogs; import "../controls-uit"; diff --git a/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml b/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml index 7965006b8b..8652e37571 100644 --- a/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml @@ -8,8 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 import QtQuick.Dialogs 1.2 as OriginalDialogs import "../controls-uit" diff --git a/interface/resources/qml/dialogs/TabletQueryDialog.qml b/interface/resources/qml/dialogs/TabletQueryDialog.qml index e21677c12c..e9830ca3ba 100644 --- a/interface/resources/qml/dialogs/TabletQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletQueryDialog.qml @@ -8,8 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 import QtQuick.Dialogs 1.2 as OriginalDialogs import "../controls-uit" diff --git a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml index 8c0501e3b4..8da12c246f 100644 --- a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml +++ b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml @@ -8,7 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 +import QtQuick 2.7 import QtQuick.Controls 1.4 import "../../controls-uit" diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index ea9ec2f6c9..77568428d2 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -1,12 +1,12 @@ -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtWebEngine 1.1; +import QtQuick 2.7 +import QtWebEngine 1.5; import Qt.labs.settings 1.0 import "../desktop" as OriginalDesktop import ".." import "." import "./toolbars" +import "../controls-uit" OriginalDesktop.Desktop { id: desktop diff --git a/interface/resources/qml/hifi/SpectatorCamera.qml b/interface/resources/qml/hifi/SpectatorCamera.qml index 3a8559ab1e..4bf80e410b 100644 --- a/interface/resources/qml/hifi/SpectatorCamera.qml +++ b/interface/resources/qml/hifi/SpectatorCamera.qml @@ -12,8 +12,7 @@ // import Hifi 1.0 as Hifi -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 import "../styles-uit" import "../controls-uit" as HifiControlsUit import "../controls" as HifiControls diff --git a/interface/resources/qml/hifi/tablet/Edit.qml b/interface/resources/qml/hifi/tablet/Edit.qml index e2e8c4362e..8df461561a 100644 --- a/interface/resources/qml/hifi/tablet/Edit.qml +++ b/interface/resources/qml/hifi/tablet/Edit.qml @@ -1,29 +1,295 @@ -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 import "../../styles-uit" +import "../../controls-uit" as HifiControls +import "../../controls" +import "../toolbars" -StackView { +ColumnLayout { id: editRoot objectName: "stack" - initialItem: Qt.resolvedUrl('EditTabView.qml') + anchors.fill: parent + + readonly property var webTabsLinks: [ + "", + "/system/html/entityList.html", + "/system/html/entityProperties.html", + "/system/html/gridControls.html", + "/system/particle_explorer/particleExplorer.html" + ] signal sendToScript(var message); - HifiConstants { id: hifi } - function pushSource(path) { - editRoot.push(Qt.resolvedUrl(path)); - editRoot.currentItem.sendToScript.connect(editRoot.sendToScript); + console.error("Edit. push source", path, Qt.resolvedUrl(path)) + editStack.push(Qt.resolvedUrl(path)); + editStack.currentItem.sendToScript.connect(editRoot.sendToScript); } function popSource() { - editRoot.pop(); + editStack.pop(); } - // Passes script messages to the item on the top of the stack function fromScript(message) { - var currentItem = editRoot.currentItem; - if (currentItem && currentItem.fromScript) - currentItem.fromScript(message); + console.error("from script", JSON.stringify(message)) + switch (message.method) { + case 'selectTab': + selectTab(message.params.id); + break; + default: + var currentItem = editStack.currentItem; + if (currentItem && currentItem.fromScript) { + currentItem.fromScript(message); + } else { + console.warn('Unrecognized message:', JSON.stringify(message)); + } + } + } + + // Changes the current tab based on tab index or title as input + function selectTab(id) { + console.error("selecting tab", id) + if (typeof id === 'number') { + if (id >= 0 && id <= 4) { + editTabView.currentIndex = id; + } else { + console.warn('Attempt to switch to invalid tab:', id); + } + } else if (typeof id === 'string'){ + switch (id.toLowerCase()) { + case 'create': + editTabView.currentIndex = 0; + break; + case 'list': + editTabView.currentIndex = 1; + break; + case 'properties': + editTabView.currentIndex = 2; + break; + case 'grid': + editTabView.currentIndex = 3; + break; + case 'particle': + editTabView.currentIndex = 4; + break; + default: + console.warn('Attempt to switch to invalid tab:', id); + } + } else { + console.warn('Attempt to switch tabs with invalid input:', JSON.stringify(id)); + } + } + spacing: 0 + + HifiConstants { id: hifi } + + TabBar { + id: editTabView + height: 60 + width: parent.width + contentWidth: parent.width + currentIndex: 0 + padding: 0 + spacing: 0 + + onCurrentIndexChanged: { + if (currentIndex === 0) { + editStack.replace(null, mainTab, {}, StackView.Immediate) + } else { + editStack.replace(null, webViewTab, + {url: Paths.defaultScripts + webTabsLinks[currentIndex]}, + StackView.Immediate) + } + } + + EditTabButton { + text: "CREATE" + } + + EditTabButton { + text: "LIST" + } + + EditTabButton { + text: "PROPERTIES" + } + + EditTabButton { + text: "GRID" + } + + EditTabButton { + text: "P" + } + } + + StackView { + id: editStack + + Layout.fillHeight: true + Layout.fillWidth: true + initialItem: mainTab//Qt.resolvedUrl('EditTabView.qml') + } + + Component { + id: mainTab + + + Rectangle { //1st tab + color: "#404040" + + Text { + color: "#ffffff" + text: "Choose an Entity Type to Create:" + font.pixelSize: 14 + font.bold: true + anchors.top: parent.top + anchors.topMargin: 28 + anchors.left: parent.left + anchors.leftMargin: 28 + } + + Flow { + id: createEntitiesFlow + spacing: 35 + anchors.right: parent.right + anchors.rightMargin: 55 + anchors.left: parent.left + anchors.leftMargin: 55 + anchors.top: parent.top + anchors.topMargin: 70 + + + NewEntityButton { + icon: "icons/create-icons/94-model-01.svg" + text: "MODEL" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newModelButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/21-cube-01.svg" + text: "CUBE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newCubeButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/22-sphere-01.svg" + text: "SPHERE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newSphereButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/24-light-01.svg" + text: "LIGHT" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newLightButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/20-text-01.svg" + text: "TEXT" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newTextButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/25-web-1-01.svg" + text: "WEB" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newWebButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/23-zone-01.svg" + text: "ZONE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newZoneButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/90-particles-01.svg" + text: "PARTICLE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newParticleButton" } + }); + editTabView.currentIndex = 4 + } + } + } + + HifiControls.Button { + id: assetServerButton + text: "Open This Domain's Asset Server" + color: hifi.buttons.black + colorScheme: hifi.colorSchemes.dark + anchors.right: parent.right + anchors.rightMargin: 55 + anchors.left: parent.left + anchors.leftMargin: 55 + anchors.top: createEntitiesFlow.bottom + anchors.topMargin: 35 + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "openAssetBrowserButton" } + }); + } + } + + HifiControls.Button { + text: "Import Entities (.json)" + color: hifi.buttons.black + colorScheme: hifi.colorSchemes.dark + anchors.right: parent.right + anchors.rightMargin: 55 + anchors.left: parent.left + anchors.leftMargin: 55 + anchors.top: assetServerButton.bottom + anchors.topMargin: 20 + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "importEntitiesButton" } + }); + } + } + } + } + + Component { + id: webViewTab + WebView {} } } + diff --git a/interface/resources/qml/hifi/tablet/EditTabButton.qml b/interface/resources/qml/hifi/tablet/EditTabButton.qml new file mode 100644 index 0000000000..761ab4d8cd --- /dev/null +++ b/interface/resources/qml/hifi/tablet/EditTabButton.qml @@ -0,0 +1,52 @@ +// +// AudioTabButton.qml +// qml/hifi/audio +// +// Created by Vlad Stelmahovsky on 8/16/2017 +// Copyright 2017 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.7 +import QtQuick.Controls 2.2 +import "../../controls-uit" as HifiControls +import "../../styles-uit" + +TabButton { + id: control + font.pixelSize: height / 2 + padding: 0 + spacing: 0 + HifiConstants { id: hifi; } + + contentItem: Text { + id: text + text: control.text + font.pixelSize: 16 + font.bold: true + color: control.checked ? "white" : "white" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + property string glyphtext: "" + HiFiGlyphs { + anchors.centerIn: parent + size: 30 + color: "#ffffff" + text: text.glyphtext + } + Component.onCompleted: { + if (control.text === "P") { + text.text = " "; + text.glyphtext = "\ue004"; + } + } + } + + background: Rectangle { + color: control.checked ? "#404040" :"black" + implicitWidth: control.contentItem.width + 42 + implicitHeight: 40 + } +} diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index 649a8e6259..ac33eaf5fa 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -9,8 +9,8 @@ // import Hifi 1.0 -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import QtGraphicalEffects 1.0 import "../../controls" import "../../styles" diff --git a/interface/resources/qml/hifi/tablet/TabletAudioBuffers.qml b/interface/resources/qml/hifi/tablet/TabletAudioBuffers.qml index 1b4d0feaca..239c2452d4 100644 --- a/interface/resources/qml/hifi/tablet/TabletAudioBuffers.qml +++ b/interface/resources/qml/hifi/tablet/TabletAudioBuffers.qml @@ -8,8 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "tabletWindows" import "../../dialogs" diff --git a/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml b/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml index dee2eed9c3..810f5bb43f 100644 --- a/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletGeneralPreferences.qml @@ -8,8 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "tabletWindows" import "../../dialogs" diff --git a/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml b/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml index 25b5be05f2..3114c79bfe 100644 --- a/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml @@ -8,8 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "tabletWindows" import "../../dialogs" diff --git a/interface/resources/qml/hifi/tablet/TabletLodPreferences.qml b/interface/resources/qml/hifi/tablet/TabletLodPreferences.qml index b502c26245..ddc116371d 100644 --- a/interface/resources/qml/hifi/tablet/TabletLodPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletLodPreferences.qml @@ -8,8 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "tabletWindows" import "../../dialogs" diff --git a/interface/resources/qml/hifi/tablet/TabletNetworkingPreferences.qml b/interface/resources/qml/hifi/tablet/TabletNetworkingPreferences.qml index 91d6140fc3..bad546a39c 100644 --- a/interface/resources/qml/hifi/tablet/TabletNetworkingPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletNetworkingPreferences.qml @@ -8,8 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "tabletWindows" import "../../dialogs" From 41f338e6adcf6d93fe6ed55670ea5410856d83e4 Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 18 Nov 2017 20:18:17 +0100 Subject: [PATCH 007/109] Port ScrollingWindow and TabletDebugWindow --- .../qml/hifi/dialogs/TabletDebugWindow.qml | 9 ++-- .../resources/qml/windows/ScrollingWindow.qml | 51 +++++++++---------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/TabletDebugWindow.qml b/interface/resources/qml/hifi/dialogs/TabletDebugWindow.qml index 22e9dc07a2..50df4dedbc 100644 --- a/interface/resources/qml/hifi/dialogs/TabletDebugWindow.qml +++ b/interface/resources/qml/hifi/dialogs/TabletDebugWindow.qml @@ -8,8 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import Hifi 1.0 as Hifi import "../../styles-uit" @@ -69,9 +69,8 @@ Rectangle { id: textArea width: parent.width height: parent.height - backgroundVisible: false - textColor: hifi.colors.white + background: Item {} + color: hifi.colors.white text:"" } - } diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 1f9b59d2b4..cf44927941 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -10,8 +10,7 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.2 import QtGraphicalEffects 1.0 import "." @@ -78,17 +77,21 @@ Window { ScrollView { id: scrollView contentItem: content - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - verticalScrollBarPolicy: Qt.ScrollBarAsNeeded + clip: true + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff anchors.fill: parent anchors.rightMargin: parent.isScrolling ? 1 : 0 anchors.bottomMargin: footerPane.height - style: ScrollViewStyle { - - padding.right: -7 // Move to right away from content. - - handle: Item { + ScrollBar.vertical: ScrollBar { + parent: scrollView + policy: ScrollBar.AsNeeded + orientation: Qt.Vertical + x: scrollView.mirrored ? 0 : scrollView.width - width + y: scrollView.topPadding + height: scrollView.availableHeight + active: scrollView.ScrollBar.horizontal.active + contentItem: Item { implicitWidth: 8 Rectangle { radius: 4 @@ -101,30 +104,24 @@ Window { } } } + } - scrollBarBackground: Item { - implicitWidth: 10 - Rectangle { - color: hifi.colors.darkGray30 - radius: 4 - anchors { - fill: parent - topMargin: -1 // Finesse size - bottomMargin: -2 - } + background: Item { + implicitWidth: 10 + Rectangle { + color: hifi.colors.darkGray30 + radius: 4 + anchors { + fill: parent + topMargin: -1 // Finesse size + bottomMargin: -2 } } - - incrementControl: Item { - visible: false - } - - decrementControl: Item { - visible: false - } } + } + function scrollBy(delta) { scrollView.flickableItem.contentY += delta; } From d92f461f1244fc5cccf2dfb8032471f6d125da7b Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 18 Nov 2017 20:44:52 +0100 Subject: [PATCH 008/109] Port ControllerSettings --- interface/resources/qml/hifi/tablet/ControllerSettings.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/ControllerSettings.qml b/interface/resources/qml/hifi/tablet/ControllerSettings.qml index 4814eaf01c..3e1a7bf139 100644 --- a/interface/resources/qml/hifi/tablet/ControllerSettings.qml +++ b/interface/resources/qml/hifi/tablet/ControllerSettings.qml @@ -6,8 +6,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import QtGraphicalEffects 1.0 import "../../styles-uit" import "../../controls" From 68b08f429c4586370f2ebca59fb8f3c7ffc667df Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 18 Nov 2017 22:49:16 +0100 Subject: [PATCH 009/109] Port Attachments to QQC2 --- .../qml/hifi/dialogs/content/AttachmentsContent.qml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml b/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml index 5c9d6822c8..8a89cd5b42 100644 --- a/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml +++ b/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml @@ -1,7 +1,6 @@ -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import QtQuick.Dialogs 1.2 as OriginalDialogs -import QtQuick.Controls.Styles 1.4 import "../../../styles-uit" import "../../../controls-uit" as HifiControls @@ -246,7 +245,7 @@ Item { } } - Action { + HifiControls.Action { id: cancelAction text: "Cancel" onTriggered: { @@ -255,7 +254,7 @@ Item { } } - Action { + HifiControls.Action { id: okAction text: "OK" onTriggered: { From 19f9af05769ad5c3061285c21870ed8bba42eb39 Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 18 Nov 2017 23:03:52 +0100 Subject: [PATCH 010/109] Port avatar preferences --- .../qml/hifi/dialogs/content/ModelBrowserContent.qml | 5 ++--- .../resources/qml/hifi/tablet/TabletAvatarPreferences.qml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/content/ModelBrowserContent.qml b/interface/resources/qml/hifi/dialogs/content/ModelBrowserContent.qml index 50fca94ff1..c9fe9840b8 100644 --- a/interface/resources/qml/hifi/dialogs/content/ModelBrowserContent.qml +++ b/interface/resources/qml/hifi/dialogs/content/ModelBrowserContent.qml @@ -1,5 +1,4 @@ import QtQuick 2.5 -import QtQuick.Controls 1.4 import "../../../controls-uit" as HifiControls @@ -40,7 +39,7 @@ Column { HifiControls.Button { action: cancelAction ; color: hifi.buttons.black; colorScheme: hifi.colorSchemes.dark } } - Action { + HifiControls.Action { id: acceptAction text: qsTr("OK") enabled: root.result ? true : false @@ -51,7 +50,7 @@ Column { } } - Action { + HifiControls.Action { id: cancelAction text: qsTr("Cancel") shortcut: Qt.Key_Escape diff --git a/interface/resources/qml/hifi/tablet/TabletAvatarPreferences.qml b/interface/resources/qml/hifi/tablet/TabletAvatarPreferences.qml index 94fb29c6a1..e824036587 100644 --- a/interface/resources/qml/hifi/tablet/TabletAvatarPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletAvatarPreferences.qml @@ -9,7 +9,7 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.2 import "tabletWindows" import "../../dialogs" From b21f66f6660463ff478df28be9f1f7ee3cfe3674 Mon Sep 17 00:00:00 2001 From: vladest Date: Sun, 19 Nov 2017 20:09:07 +0100 Subject: [PATCH 011/109] Port PlaySampleSound to QQC2. Fix crash on press down key in scroll window --- interface/resources/qml/ToolWindow.qml | 4 +- .../qml/hifi/audio/PlaySampleSound.qml | 49 +++++++++---------- .../resources/qml/windows/ScrollingWindow.qml | 14 ++---- 3 files changed, 30 insertions(+), 37 deletions(-) diff --git a/interface/resources/qml/ToolWindow.qml b/interface/resources/qml/ToolWindow.qml index b1120058f9..bfc7758348 100644 --- a/interface/resources/qml/ToolWindow.qml +++ b/interface/resources/qml/ToolWindow.qml @@ -56,8 +56,8 @@ ScrollingWindow { id: toolWindowTabViewItem height: pane.scrollHeight width: pane.contentWidth - anchors.left: parent.left - anchors.top: parent.top + anchors.left: parent !== null ? parent.left : undefined + anchors.top: parent !== null ? parent.top : undefined TabView { id: tabView diff --git a/interface/resources/qml/hifi/audio/PlaySampleSound.qml b/interface/resources/qml/hifi/audio/PlaySampleSound.qml index dec2e9bfc9..4b0e32ee12 100644 --- a/interface/resources/qml/hifi/audio/PlaySampleSound.qml +++ b/interface/resources/qml/hifi/audio/PlaySampleSound.qml @@ -9,9 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import "../../styles-uit" @@ -57,31 +56,31 @@ RowLayout { HifiConstants { id: hifi; } Button { - style: ButtonStyle { - background: Rectangle { - implicitWidth: 20; - implicitHeight: 20; - radius: hifi.buttons.radius; - gradient: Gradient { - GradientStop { - position: 0.2; - color: isPlaying ? hifi.buttons.colorStart[hifi.buttons.blue] : hifi.buttons.colorStart[hifi.buttons.black]; - } - GradientStop { - position: 1.0; - color: isPlaying ? hifi.buttons.colorFinish[hifi.buttons.blue] : hifi.buttons.colorFinish[hifi.buttons.black]; - } + id: control + background: Rectangle { + implicitWidth: 20; + implicitHeight: 20; + radius: hifi.buttons.radius; + gradient: Gradient { + GradientStop { + position: 0.2; + color: isPlaying ? hifi.buttons.colorStart[hifi.buttons.blue] : hifi.buttons.colorStart[hifi.buttons.black]; + } + GradientStop { + position: 1.0; + color: isPlaying ? hifi.buttons.colorFinish[hifi.buttons.blue] : hifi.buttons.colorFinish[hifi.buttons.black]; } } - label: HiFiGlyphs { - // absolutely position due to asymmetry in glyph - x: isPlaying ? 0 : 1; - y: 1; - size: 14; - color: (control.pressed || control.hovered) ? (isPlaying ? "black" : hifi.colors.primaryHighlight) : "white"; - text: isPlaying ? hifi.glyphs.stop_square : hifi.glyphs.playback_play; - } } + contentItem: HiFiGlyphs { + // absolutely position due to asymmetry in glyph +// x: isPlaying ? 0 : 1; +// y: 1; + size: 14; + color: (control.pressed || control.hovered) ? (isPlaying ? "black" : hifi.colors.primaryHighlight) : "white"; + text: isPlaying ? hifi.glyphs.stop_square : hifi.glyphs.playback_play; + } + onClicked: isPlaying ? stopSound() : playSound(); } diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index cf44927941..840432f262 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -43,7 +43,9 @@ Window { // type should only consist of logic sized areas, with nothing drawn (although the // default value for the frame property does include visual decorations) property var pane: Item { - property bool isScrolling: scrollView.height < scrollView.contentItem.height + property bool isScrolling: scrollView.contentChildren.length > 0 ? + (scrollView.height < scrollView.contentChildren[0].height) : + false property int contentWidth: scrollView.width - (isScrolling ? 10 : 0) property int scrollHeight: scrollView.height @@ -76,7 +78,7 @@ Window { ScrollView { id: scrollView - contentItem: content + contentChildren: content clip: true ScrollBar.horizontal.policy: ScrollBar.AlwaysOff anchors.fill: parent @@ -84,13 +86,7 @@ Window { anchors.bottomMargin: footerPane.height ScrollBar.vertical: ScrollBar { - parent: scrollView policy: ScrollBar.AsNeeded - orientation: Qt.Vertical - x: scrollView.mirrored ? 0 : scrollView.width - width - y: scrollView.topPadding - height: scrollView.availableHeight - active: scrollView.ScrollBar.horizontal.active contentItem: Item { implicitWidth: 8 Rectangle { @@ -118,10 +114,8 @@ Window { } } } - } - function scrollBy(delta) { scrollView.flickableItem.contentY += delta; } From 50ed9e2b2a291ec6b7c57aa7283bb2d8d2c1eaac Mon Sep 17 00:00:00 2001 From: vladest Date: Sun, 19 Nov 2017 22:03:38 +0100 Subject: [PATCH 012/109] Port CheckBox to QQC2 --- .../qml/LoginDialog/LinkAccountBody.qml | 2 +- .../resources/qml/controls-uit/CheckBox.qml | 147 +++++++++--------- .../resources/qml/controls-uit/Label.qml | 2 +- .../qml/styles-uit/RalewaySemiBold.qml | 2 +- 4 files changed, 78 insertions(+), 75 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 300bcd46f0..76b1e91066 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -170,7 +170,7 @@ Item { } } - CheckBoxQQC2 { + CheckBox { id: showPassword text: "Show password" } diff --git a/interface/resources/qml/controls-uit/CheckBox.qml b/interface/resources/qml/controls-uit/CheckBox.qml index 22b25671c3..86a7742d16 100644 --- a/interface/resources/qml/controls-uit/CheckBox.qml +++ b/interface/resources/qml/controls-uit/CheckBox.qml @@ -8,9 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.2 +import QtQuick.Controls 2.2 as Original import "../styles-uit" @@ -28,85 +27,89 @@ Original.CheckBox { property bool wrap: true; readonly property int checkSize: Math.max(boxSize - 8, 10) readonly property int checkRadius: 2 - activeFocusOnPress: true + focusPolicy: Qt.ClickFocus + hoverEnabled: true onClicked: { tabletInterface.playSound(TabletEnums.ButtonClick); } -// TODO: doesnt works for QQC1. check with QQC2 -// onHovered: { -// tabletInterface.playSound(TabletEnums.ButtonHover); -// } + onHoveredChanged: { + if (hovered) { + tabletInterface.playSound(TabletEnums.ButtonHover); + } + } - style: CheckBoxStyle { - indicator: Rectangle { - id: box + + indicator: Rectangle { + id: box + width: boxSize + height: boxSize + radius: boxRadius + y: parent.height / 2 - height / 2 + border.width: 1 + border.color: pressed || hovered + ? hifi.colors.checkboxCheckedBorder + : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) + + gradient: Gradient { + GradientStop { + position: 0.2 + color: pressed || hovered + ? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightStart) + : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart) + } + GradientStop { + position: 1.0 + color: pressed || hovered + ? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightFinish) + : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) + } + } + + Rectangle { + visible: pressed || hovered + anchors.centerIn: parent + id: innerBox + width: checkSize - 4 + height: width + radius: checkRadius + color: hifi.colors.checkboxCheckedBorder + } + + Rectangle { + id: check + width: checkSize + height: checkSize + radius: checkRadius + anchors.centerIn: parent + color: isRedCheck ? hifi.colors.checkboxCheckedRed : hifi.colors.checkboxChecked + border.width: 2 + border.color: isRedCheck? hifi.colors.checkboxCheckedBorderRed : hifi.colors.checkboxCheckedBorder + visible: checked && !pressed || !checked && pressed + } + + Rectangle { + id: disabledOverlay + visible: !enabled width: boxSize height: boxSize radius: boxRadius border.width: 1 - border.color: pressed || hovered - ? hifi.colors.checkboxCheckedBorder - : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) - - gradient: Gradient { - GradientStop { - position: 0.2 - color: pressed || hovered - ? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightStart) - : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart) - } - GradientStop { - position: 1.0 - color: pressed || hovered - ? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightFinish) - : (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) - } - } - - Rectangle { - visible: pressed || hovered - anchors.centerIn: parent - id: innerBox - width: checkSize - 4 - height: width - radius: checkRadius - color: hifi.colors.checkboxCheckedBorder - } - - Rectangle { - id: check - width: checkSize - height: checkSize - radius: checkRadius - anchors.centerIn: parent - color: isRedCheck ? hifi.colors.checkboxCheckedRed : hifi.colors.checkboxChecked - border.width: 2 - border.color: isRedCheck? hifi.colors.checkboxCheckedBorderRed : hifi.colors.checkboxCheckedBorder - visible: checked && !pressed || !checked && pressed - } - - Rectangle { - id: disabledOverlay - visible: !enabled - width: boxSize - height: boxSize - radius: boxRadius - border.width: 1 - border.color: hifi.colors.baseGrayHighlight - color: hifi.colors.baseGrayHighlight - opacity: 0.5 - } - } - - label: Label { - text: control.text - color: control.color - x: 2 - wrapMode: checkBox.wrap ? Text.Wrap : Text.NoWrap - elide: checkBox.wrap ? Text.ElideNone : Text.ElideRight - enabled: checkBox.enabled + border.color: hifi.colors.baseGrayHighlight + color: hifi.colors.baseGrayHighlight + opacity: 0.5 } } + + contentItem: Label { + text: checkBox.text + color: checkBox.color + x: 2 + verticalAlignment: Text.AlignVCenter + wrapMode: checkBox.wrap ? Text.Wrap : Text.NoWrap + elide: checkBox.wrap ? Text.ElideNone : Text.ElideRight + enabled: checkBox.enabled + leftPadding: checkBox.indicator.width + checkBox.spacing + } } diff --git a/interface/resources/qml/controls-uit/Label.qml b/interface/resources/qml/controls-uit/Label.qml index 1dc3aa0dd4..4c7051b495 100644 --- a/interface/resources/qml/controls-uit/Label.qml +++ b/interface/resources/qml/controls-uit/Label.qml @@ -8,7 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 +import QtQuick 2.7 import "../styles-uit" diff --git a/interface/resources/qml/styles-uit/RalewaySemiBold.qml b/interface/resources/qml/styles-uit/RalewaySemiBold.qml index fe3a42dd6c..2d7a7f46a2 100644 --- a/interface/resources/qml/styles-uit/RalewaySemiBold.qml +++ b/interface/resources/qml/styles-uit/RalewaySemiBold.qml @@ -8,7 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 +import QtQuick 2.7 Text { id: root From f991379c9c108b059d4a4673455c6a1be51e8484 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 20 Nov 2017 17:02:34 +0100 Subject: [PATCH 013/109] Fix scroll bar --- interface/resources/qml/windows/ScrollingWindow.qml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 840432f262..df15526039 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -43,8 +43,8 @@ Window { // type should only consist of logic sized areas, with nothing drawn (although the // default value for the frame property does include visual decorations) property var pane: Item { - property bool isScrolling: scrollView.contentChildren.length > 0 ? - (scrollView.height < scrollView.contentChildren[0].height) : + property bool isScrolling: /*scrollView.contentChildren.length > 0 ? + (scrollView.height < scrollView.contentChildren[0].height) :*/ false property int contentWidth: scrollView.width - (isScrolling ? 10 : 0) property int scrollHeight: scrollView.height @@ -86,7 +86,15 @@ Window { anchors.bottomMargin: footerPane.height ScrollBar.vertical: ScrollBar { + id: control policy: ScrollBar.AsNeeded + parent: scrollView + x: scrollView.width - width + y: scrollView.topPadding + height: scrollView.availableHeight + active: scrollView.ScrollBar.vertical.active + visible: control.size < 1.0 + contentItem: Item { implicitWidth: 8 Rectangle { From 4e38b3bace80715188ca915f0b1d7a9a189e21ab Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 20 Nov 2017 20:35:41 +0100 Subject: [PATCH 014/109] Started working on ComboBox. Add background for scroll bar --- .../resources/qml/controls-uit/ComboBox.qml | 28 ++++++++--------- .../resources/qml/windows/ScrollingWindow.qml | 30 +++++++++---------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/interface/resources/qml/controls-uit/ComboBox.qml b/interface/resources/qml/controls-uit/ComboBox.qml index d672fa6387..59be9134bc 100644 --- a/interface/resources/qml/controls-uit/ComboBox.qml +++ b/interface/resources/qml/controls-uit/ComboBox.qml @@ -8,9 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "../styles-uit" import "../controls-uit" as HifiControls @@ -177,22 +176,21 @@ FocusScope { id: scrollView height: root.dropdownHeight width: root.width + 4 - property bool hoverEnabled: false; + hoverEnabled: false; - style: ScrollViewStyle { - decrementControl: Item { - visible: false - } - incrementControl: Item { - visible: false - } - scrollBarBackground: Rectangle{ +// style: ScrollViewStyle { +// decrementControl: Item { +// visible: false +// } +// incrementControl: Item { +// visible: false +// } + background: Rectangle{ implicitWidth: 20 color: hifi.colors.baseGray } - handle: - Rectangle { + contentItem: Rectangle { implicitWidth: 16 anchors.left: parent.left anchors.leftMargin: 3 @@ -201,7 +199,7 @@ FocusScope { radius: 6 color: hifi.colors.lightGrayText } - } +// } ListView { id: listView diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index df15526039..1966380709 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -43,8 +43,8 @@ Window { // type should only consist of logic sized areas, with nothing drawn (although the // default value for the frame property does include visual decorations) property var pane: Item { - property bool isScrolling: /*scrollView.contentChildren.length > 0 ? - (scrollView.height < scrollView.contentChildren[0].height) :*/ + property bool isScrolling: scrollView.contentChildren.length > 0 ? + (scrollView.height < scrollView.contentChildren[0].height) : false property int contentWidth: scrollView.width - (isScrolling ? 10 : 0) property int scrollHeight: scrollView.height @@ -94,7 +94,18 @@ Window { height: scrollView.availableHeight active: scrollView.ScrollBar.vertical.active visible: control.size < 1.0 - + background: Item { + implicitWidth: 10 + Rectangle { + color: hifi.colors.darkGray30 + radius: 4 + anchors { + fill: parent + topMargin: -1 // Finesse size + bottomMargin: -2 + } + } + } contentItem: Item { implicitWidth: 8 Rectangle { @@ -110,18 +121,7 @@ Window { } } - background: Item { - implicitWidth: 10 - Rectangle { - color: hifi.colors.darkGray30 - radius: 4 - anchors { - fill: parent - topMargin: -1 // Finesse size - bottomMargin: -2 - } - } - } + } function scrollBy(delta) { From da5090fd496220e5b8ee270c9afd40c49b4b0e6f Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 27 Nov 2017 19:43:17 +0100 Subject: [PATCH 015/109] Implemented more close to QQC2 ideology --- .../resources/qml/controls-uit/ComboBox.qml | 212 +++++++++++------- .../resources/qml/controls-uit/ScrollBar.qml | 41 ++++ 2 files changed, 173 insertions(+), 80 deletions(-) create mode 100644 interface/resources/qml/controls-uit/ScrollBar.qml diff --git a/interface/resources/qml/controls-uit/ComboBox.qml b/interface/resources/qml/controls-uit/ComboBox.qml index 59be9134bc..04b1362202 100644 --- a/interface/resources/qml/controls-uit/ComboBox.qml +++ b/interface/resources/qml/controls-uit/ComboBox.qml @@ -39,72 +39,128 @@ FocusScope { implicitHeight: comboBox.height; focus: true - Rectangle { - id: background - gradient: Gradient { - GradientStop { - position: 0.2 - color: popup.visible - ? (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) - : (isLightColorScheme ? hifi.colors.dropDownLightStart : hifi.colors.dropDownDarkStart) - } - GradientStop { - position: 1.0 - color: popup.visible - ? (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) - : (isLightColorScheme ? hifi.colors.dropDownLightFinish : hifi.colors.dropDownDarkFinish) - } - } - anchors.fill: parent - } - - SystemPalette { id: palette } + //SystemPalette { id: palette } ComboBox { id: comboBox anchors.fill: parent - visible: false + hoverEnabled: true + visible: true + height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. - } - - FiraSansSemiBold { - id: textField - anchors { - left: parent.left - leftMargin: hifi.dimensions.textPadding - right: dropIcon.left - verticalCenter: parent.verticalCenter - } - size: hifi.fontSizes.textFieldInput - text: comboBox.currentText - elide: Text.ElideRight - color: controlHover.containsMouse || popup.visible ? hifi.colors.baseGray : (isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText ) - } - - Item { - id: dropIcon - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - height: background.height - width: height - Rectangle { - width: 1 - height: parent.height - anchors.top: parent.top - anchors.left: parent.left - color: isLightColorScheme ? hifi.colors.faintGray : hifi.colors.baseGray - } - HiFiGlyphs { - anchors { - top: parent.top - topMargin: -11 - horizontalCenter: parent.horizontalCenter + background: Rectangle { + id: background + gradient: Gradient { + GradientStop { + position: 0.2 + color: comboBox.popup.visible + ? (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) + : (isLightColorScheme ? hifi.colors.dropDownLightStart : hifi.colors.dropDownDarkStart) + } + GradientStop { + position: 1.0 + color: comboBox.popup.visible + ? (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) + : (isLightColorScheme ? hifi.colors.dropDownLightFinish : hifi.colors.dropDownDarkFinish) + } } - size: hifi.dimensions.spinnerSize - text: hifi.glyphs.caratDn - color: controlHover.containsMouse || popup.visible ? hifi.colors.baseGray : (isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText) } - } + indicator: Item { + id: dropIcon + anchors { right: parent.right; verticalCenter: parent.verticalCenter } + height: background.height + width: height + Rectangle { + width: 1 + height: parent.height + anchors.top: parent.top + anchors.left: parent.left + color: isLightColorScheme ? hifi.colors.faintGray : hifi.colors.baseGray + } + HiFiGlyphs { + anchors { top: parent.top; topMargin: -11; horizontalCenter: parent.horizontalCenter } + size: hifi.dimensions.spinnerSize + text: hifi.glyphs.caratDn + color: comboBox.hovered || comboBox.popup.visible ? hifi.colors.baseGray : (isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText) + } + } + + contentItem: FiraSansSemiBold { + id: textField + anchors { + left: parent.left + leftMargin: hifi.dimensions.textPadding + verticalCenter: parent.verticalCenter + } + size: hifi.fontSizes.textFieldInput + text: comboBox.currentText + elide: Text.ElideRight + color: comboBox.hovered || comboBox.popup.visible ? hifi.colors.baseGray : (isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText ) + } + + delegate: ItemDelegate { + id: itemDelegate + hoverEnabled: true + width: root.width + 4 + height: popupText.implicitHeight * 1.4 + + onHoveredChanged: { + itemDelegate.highlighted = hovered; + } + + background: Rectangle { + color: itemDelegate.highlighted ? hifi.colors.primaryHighlight + : (isLightColorScheme ? hifi.colors.dropDownPressedLight + : hifi.colors.dropDownPressedDark) + } + + contentItem: FiraSansSemiBold { + id: popupText + anchors.left: parent.left + anchors.leftMargin: hifi.dimensions.textPadding + anchors.verticalCenter: parent.verticalCenter + text: comboBox.model[index] ? comboBox.model[index] : (comboBox.model.get && comboBox.model.get(index).text ? comboBox.model.get(index).text : "") + size: hifi.fontSizes.textFieldInput + color: hifi.colors.baseGray + } + } + popup: Popup { + y: comboBox.height - 1 + width: comboBox.width + implicitHeight: dropdownHeight + padding: 1 + + contentItem: ListView { + id: listView + clip: true + implicitHeight: dropdownHeight + model: comboBox.popup.visible ? comboBox.delegateModel : null + currentIndex: comboBox.highlightedIndex + delegate: comboBox.delegate + ScrollBar.vertical: HifiControls.ScrollBar { + id: scrollbar + parent: listView + policy: ScrollBar.AsNeeded + visible: size < 1.0 + } + } + + background: Rectangle { + color: hifi.colors.baseGray + } + } +// MouseArea { +// id: popupHover +// anchors.fill: parent; +// hoverEnabled: scrollView.hoverEnabled; +// onEntered: listView.currentIndex = index; +// onClicked: popup.selectSpecificItem(index); +// } +// } +// } + } +/* MouseArea { id: controlHover hoverEnabled: true @@ -178,28 +234,20 @@ FocusScope { width: root.width + 4 hoverEnabled: false; -// style: ScrollViewStyle { -// decrementControl: Item { -// visible: false -// } -// incrementControl: Item { -// visible: false -// } - background: Rectangle{ - implicitWidth: 20 - color: hifi.colors.baseGray - } + background: Rectangle{ + implicitWidth: 20 + color: hifi.colors.baseGray + } - contentItem: Rectangle { - implicitWidth: 16 - anchors.left: parent.left - anchors.leftMargin: 3 - anchors.top: parent.top - anchors.bottom: parent.bottom - radius: 6 - color: hifi.colors.lightGrayText - } -// } + contentItem: Rectangle { + implicitWidth: 16 + anchors.left: parent.left + anchors.leftMargin: 3 + anchors.top: parent.top + anchors.bottom: parent.bottom + radius: 6 + color: hifi.colors.lightGrayText + } ListView { id: listView @@ -230,7 +278,7 @@ FocusScope { } } } - +*/ HifiControls.Label { id: comboBoxLabel text: root.label @@ -243,5 +291,9 @@ FocusScope { Component.onCompleted: { isDesktop = (typeof desktop !== "undefined"); + comboBox.popup.closePolicy = Popup.CloseOnPressOutside + comboBox.popup.height = dropdownHeight + //TODO: do we need this? + comboBox.popup.z = isDesktop ? desktop.zLevels.menu : 12 } } diff --git a/interface/resources/qml/controls-uit/ScrollBar.qml b/interface/resources/qml/controls-uit/ScrollBar.qml new file mode 100644 index 0000000000..125e84e585 --- /dev/null +++ b/interface/resources/qml/controls-uit/ScrollBar.qml @@ -0,0 +1,41 @@ +// +// ScrollBar.qml +// +// Created by Vlad Stelmahovsky on 27 Nov 2017 +// Copyright 2016 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.7 +import QtQuick.Controls 2.2 + +import "../styles-uit" + +ScrollBar { + visible: size < 1.0 + + HifiConstants { id: hifi } + property int colorScheme: hifi.colorSchemes.light + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + + background: Item { + implicitWidth: hifi.dimensions.scrollbarBackgroundWidth + Rectangle { + anchors { fill: parent; topMargin: 3; bottomMargin: 3 } + radius: hifi.dimensions.scrollbarHandleWidth/2 + color: isLightColorScheme ? hifi.colors.tableScrollBackgroundLight + : hifi.colors.tableScrollBackgroundDark + } + } + + contentItem: Item { + implicitWidth: hifi.dimensions.scrollbarHandleWidth + Rectangle { + anchors { fill: parent; topMargin: 1; bottomMargin: 1 } + radius: hifi.dimensions.scrollbarHandleWidth/2 + color: isLightColorScheme ? hifi.colors.tableScrollHandleLight : hifi.colors.tableScrollHandleDark + } + } +} From 80eb203008f43508fe1b9828d01e1ae23cf485c3 Mon Sep 17 00:00:00 2001 From: vladest Date: Tue, 28 Nov 2017 20:20:58 +0100 Subject: [PATCH 016/109] More precise handle placing. some logging added --- .../resources/qml/controls-uit/ComboBox.qml | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/interface/resources/qml/controls-uit/ComboBox.qml b/interface/resources/qml/controls-uit/ComboBox.qml index 04b1362202..e6cf78601f 100644 --- a/interface/resources/qml/controls-uit/ComboBox.qml +++ b/interface/resources/qml/controls-uit/ComboBox.qml @@ -39,15 +39,21 @@ FocusScope { implicitHeight: comboBox.height; focus: true - //SystemPalette { id: palette } - ComboBox { id: comboBox anchors.fill: parent hoverEnabled: true visible: true - height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. + + onPressedChanged: { + console.warn("on pressed", pressed, popup.visible) + if (!pressed && popup.visible) { + popup.visible = false + down = undefined + } + } + background: Rectangle { id: background gradient: Gradient { @@ -120,7 +126,9 @@ FocusScope { anchors.left: parent.left anchors.leftMargin: hifi.dimensions.textPadding anchors.verticalCenter: parent.verticalCenter - text: comboBox.model[index] ? comboBox.model[index] : (comboBox.model.get && comboBox.model.get(index).text ? comboBox.model.get(index).text : "") + text: comboBox.model[index] ? comboBox.model[index] + : (comboBox.model.get && comboBox.model.get(index).text ? + comboBox.model.get(index).text : "") size: hifi.fontSizes.textFieldInput color: hifi.colors.baseGray } @@ -128,13 +136,16 @@ FocusScope { popup: Popup { y: comboBox.height - 1 width: comboBox.width - implicitHeight: dropdownHeight - padding: 1 + implicitHeight: listView.contentHeight > dropdownHeight ? dropdownHeight + : listView.contentHeight + padding: 0 + topPadding: 1 + closePolicy: Popup.NoAutoClose + onVisibleChanged: console.warn("popup", visible) contentItem: ListView { id: listView clip: true - implicitHeight: dropdownHeight model: comboBox.popup.visible ? comboBox.delegateModel : null currentIndex: comboBox.highlightedIndex delegate: comboBox.delegate @@ -291,8 +302,6 @@ FocusScope { Component.onCompleted: { isDesktop = (typeof desktop !== "undefined"); - comboBox.popup.closePolicy = Popup.CloseOnPressOutside - comboBox.popup.height = dropdownHeight //TODO: do we need this? comboBox.popup.z = isDesktop ? desktop.zLevels.menu : 12 } From ac7a5ebc947b7720dca7f4be1aa64bab018d3af4 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 30 Nov 2017 10:39:01 +0100 Subject: [PATCH 017/109] ComboBox: fix closing popup. Started to implement keyboard support --- .../resources/qml/controls-uit/ComboBox.qml | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/controls-uit/ComboBox.qml b/interface/resources/qml/controls-uit/ComboBox.qml index e6cf78601f..1fc95de129 100644 --- a/interface/resources/qml/controls-uit/ComboBox.qml +++ b/interface/resources/qml/controls-uit/ComboBox.qml @@ -46,16 +46,18 @@ FocusScope { visible: true height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. - onPressedChanged: { - console.warn("on pressed", pressed, popup.visible) - if (!pressed && popup.visible) { - popup.visible = false - down = undefined - } - } + function previousItem() { listView.currentIndex = (listView.currentIndex + listView.count - 1) % listView.count; } + function nextItem() { listView.currentIndex = (listView.currentIndex + listView.count + 1) % listView.count; } + function selectCurrentItem() { root.currentIndex = listView.currentIndex; close(); /*hideList();*/ } + function selectSpecificItem(index) { root.currentIndex = index; close();/*hideList();*/ } + + Keys.onUpPressed: previousItem(); + Keys.onDownPressed: nextItem(); + Keys.onSpacePressed: selectCurrentItem(); + Keys.onRightPressed: selectCurrentItem(); + Keys.onReturnPressed: selectCurrentItem(); background: Rectangle { - id: background gradient: Gradient { GradientStop { position: 0.2 @@ -75,7 +77,7 @@ FocusScope { indicator: Item { id: dropIcon anchors { right: parent.right; verticalCenter: parent.verticalCenter } - height: background.height + height: root.height width: height Rectangle { width: 1 @@ -140,8 +142,10 @@ FocusScope { : listView.contentHeight padding: 0 topPadding: 1 - closePolicy: Popup.NoAutoClose - onVisibleChanged: console.warn("popup", visible) + + onClosed: { + root.accepted() + } contentItem: ListView { id: listView @@ -303,6 +307,6 @@ FocusScope { Component.onCompleted: { isDesktop = (typeof desktop !== "undefined"); //TODO: do we need this? - comboBox.popup.z = isDesktop ? desktop.zLevels.menu : 12 + //comboBox.popup.z = isDesktop ? desktop.zLevels.menu : 12 } } From 0f4329be693e7422e42961f02a5ee5bab359a40c Mon Sep 17 00:00:00 2001 From: vladest Date: Sun, 3 Dec 2017 22:45:57 +0100 Subject: [PATCH 018/109] Added keyboard support. Cleanup --- .../resources/qml/controls-uit/ComboBox.qml | 143 ++---------------- 1 file changed, 9 insertions(+), 134 deletions(-) diff --git a/interface/resources/qml/controls-uit/ComboBox.qml b/interface/resources/qml/controls-uit/ComboBox.qml index 1fc95de129..ab8a6c2344 100644 --- a/interface/resources/qml/controls-uit/ComboBox.qml +++ b/interface/resources/qml/controls-uit/ComboBox.qml @@ -23,6 +23,7 @@ FocusScope { property alias comboBox: comboBox readonly property alias currentText: comboBox.currentText; property alias currentIndex: comboBox.currentIndex; + property int currentHighLightedIndex: comboBox.currentIndex; property int dropdownHeight: 480 property int colorScheme: hifi.colorSchemes.light @@ -46,9 +47,9 @@ FocusScope { visible: true height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control. - function previousItem() { listView.currentIndex = (listView.currentIndex + listView.count - 1) % listView.count; } - function nextItem() { listView.currentIndex = (listView.currentIndex + listView.count + 1) % listView.count; } - function selectCurrentItem() { root.currentIndex = listView.currentIndex; close(); /*hideList();*/ } + function previousItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count - 1) % comboBox.count; } + function nextItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count + 1) % comboBox.count; } + function selectCurrentItem() { root.currentIndex = root.currentHighLightedIndex; close(); /*hideList();*/ } function selectSpecificItem(index) { root.currentIndex = index; close();/*hideList();*/ } Keys.onUpPressed: previousItem(); @@ -112,9 +113,12 @@ FocusScope { hoverEnabled: true width: root.width + 4 height: popupText.implicitHeight * 1.4 + highlighted: root.currentHighLightedIndex == index onHoveredChanged: { - itemDelegate.highlighted = hovered; + if (hovered) { + root.currentHighLightedIndex = index + } } background: Rectangle { @@ -151,7 +155,7 @@ FocusScope { id: listView clip: true model: comboBox.popup.visible ? comboBox.delegateModel : null - currentIndex: comboBox.highlightedIndex + currentIndex: root.currentHighLightedIndex delegate: comboBox.delegate ScrollBar.vertical: HifiControls.ScrollBar { id: scrollbar @@ -165,135 +169,8 @@ FocusScope { color: hifi.colors.baseGray } } -// MouseArea { -// id: popupHover -// anchors.fill: parent; -// hoverEnabled: scrollView.hoverEnabled; -// onEntered: listView.currentIndex = index; -// onClicked: popup.selectSpecificItem(index); -// } -// } -// } - } -/* - MouseArea { - id: controlHover - hoverEnabled: true - anchors.fill: parent - onClicked: toggleList(); } - function toggleList() { - if (popup.visible) { - hideList(); - } else { - showList(); - } - } - - function showList() { - var r; - if (isDesktop) { - r = desktop.mapFromItem(root, 0, 0, root.width, root.height); - } else { - r = mapFromItem(root, 0, 0, root.width, root.height); - } - var y = r.y + r.height; - var bottom = y + scrollView.height; - var height = isDesktop ? desktop.height : tabletRoot.height; - if (bottom > height) { - y -= bottom - height + 8; - } - scrollView.x = r.x; - scrollView.y = y; - popup.visible = true; - popup.forceActiveFocus(); - listView.currentIndex = root.currentIndex; - scrollView.hoverEnabled = true; - } - - function hideList() { - popup.visible = false; - scrollView.hoverEnabled = false; - root.accepted(); - } - - FocusScope { - id: popup - parent: isDesktop ? desktop : root - anchors.fill: parent - z: isDesktop ? desktop.zLevels.menu : 12 - visible: false - focus: true - - MouseArea { - anchors.fill: parent - onClicked: hideList(); - } - - function previousItem() { listView.currentIndex = (listView.currentIndex + listView.count - 1) % listView.count; } - function nextItem() { listView.currentIndex = (listView.currentIndex + listView.count + 1) % listView.count; } - function selectCurrentItem() { root.currentIndex = listView.currentIndex; hideList(); } - function selectSpecificItem(index) { root.currentIndex = index; hideList(); } - - Keys.onUpPressed: previousItem(); - Keys.onDownPressed: nextItem(); - Keys.onSpacePressed: selectCurrentItem(); - Keys.onRightPressed: selectCurrentItem(); - Keys.onReturnPressed: selectCurrentItem(); - Keys.onEscapePressed: hideList(); - - ScrollView { - id: scrollView - height: root.dropdownHeight - width: root.width + 4 - hoverEnabled: false; - - background: Rectangle{ - implicitWidth: 20 - color: hifi.colors.baseGray - } - - contentItem: Rectangle { - implicitWidth: 16 - anchors.left: parent.left - anchors.leftMargin: 3 - anchors.top: parent.top - anchors.bottom: parent.bottom - radius: 6 - color: hifi.colors.lightGrayText - } - - ListView { - id: listView - height: textField.height * count * 1.4 - model: root.model - delegate: Rectangle { - width: root.width + 4 - height: popupText.implicitHeight * 1.4 - color: (listView.currentIndex === index) ? hifi.colors.primaryHighlight : - (isLightColorScheme ? hifi.colors.dropDownPressedLight : hifi.colors.dropDownPressedDark) - FiraSansSemiBold { - anchors.left: parent.left - anchors.leftMargin: hifi.dimensions.textPadding - anchors.verticalCenter: parent.verticalCenter - id: popupText - text: listView.model[index] ? listView.model[index] : (listView.model.get && listView.model.get(index).text ? listView.model.get(index).text : "") - size: hifi.fontSizes.textFieldInput - color: hifi.colors.baseGray - } - MouseArea { - id: popupHover - anchors.fill: parent; - hoverEnabled: scrollView.hoverEnabled; - onEntered: listView.currentIndex = index; - onClicked: popup.selectSpecificItem(index); - } - } - } - } - } -*/ HifiControls.Label { id: comboBoxLabel text: root.label @@ -306,7 +183,5 @@ FocusScope { Component.onCompleted: { isDesktop = (typeof desktop !== "undefined"); - //TODO: do we need this? - //comboBox.popup.z = isDesktop ? desktop.zLevels.menu : 12 } } From 3e118c58a1392daa9f0754b0dc5f0355dbd32339 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 4 Dec 2017 12:51:57 +0100 Subject: [PATCH 019/109] Moved RadiButton and Slider --- .../qml/controls-uit/RadioButton.qml | 92 ++++++++-------- .../resources/qml/controls-uit/Slider.qml | 103 +++++++++--------- 2 files changed, 97 insertions(+), 98 deletions(-) diff --git a/interface/resources/qml/controls-uit/RadioButton.qml b/interface/resources/qml/controls-uit/RadioButton.qml index 65d36d2dcb..17fa8e746e 100644 --- a/interface/resources/qml/controls-uit/RadioButton.qml +++ b/interface/resources/qml/controls-uit/RadioButton.qml @@ -9,8 +9,7 @@ // import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.2 as Original import "../styles-uit" import "../controls-uit" as HifiControls @@ -21,6 +20,8 @@ Original.RadioButton { id: radioButton HifiConstants { id: hifi } + hoverEnabled: true + property int colorScheme: hifi.colorSchemes.light readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light @@ -33,50 +34,49 @@ Original.RadioButton { tabletInterface.playSound(TabletEnums.ButtonClick); } -// TODO: doesnt works for QQC1. check with QQC2 -// onHovered: { -// tabletInterface.playSound(TabletEnums.ButtonHover); -// } - - style: RadioButtonStyle { - indicator: Rectangle { - id: box - width: boxSize - height: boxSize - radius: 7 - gradient: Gradient { - GradientStop { - position: 0.2 - color: pressed || hovered - ? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkStart : hifi.colors.checkboxLightStart) - : (radioButton.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart) - } - GradientStop { - position: 1.0 - color: pressed || hovered - ? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkFinish : hifi.colors.checkboxLightFinish) - : (radioButton.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) - } - } - - Rectangle { - id: check - width: checkSize - height: checkSize - radius: 7 - anchors.centerIn: parent - color: "#00B4EF" - border.width: 1 - border.color: "#36CDFF" - visible: checked && !pressed || !checked && pressed - } - } - - label: RalewaySemiBold { - text: control.text - size: hifi.fontSizes.inputLabel - color: isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText - x: radioButton.boxSize / 2 + onHoveredChanged: { + if (hovered) { + tabletInterface.playSound(TabletEnums.ButtonHover); } } + + indicator: Rectangle { + id: box + width: boxSize + height: boxSize + radius: 7 + gradient: Gradient { + GradientStop { + position: 0.2 + color: pressed || hovered + ? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkStart : hifi.colors.checkboxLightStart) + : (radioButton.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart) + } + GradientStop { + position: 1.0 + color: pressed || hovered + ? (radioButton.isLightColorScheme ? hifi.colors.checkboxDarkFinish : hifi.colors.checkboxLightFinish) + : (radioButton.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish) + } + } + + Rectangle { + id: check + width: checkSize + height: checkSize + radius: 7 + anchors.centerIn: parent + color: "#00B4EF" + border.width: 1 + border.color: "#36CDFF" + visible: checked && !pressed || !checked && pressed + } + } + + contentItem: RalewaySemiBold { + text: radioButton.text + size: hifi.fontSizes.inputLabel + color: isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText + x: radioButton.boxSize / 2 + } } diff --git a/interface/resources/qml/controls-uit/Slider.qml b/interface/resources/qml/controls-uit/Slider.qml index 89bae9bcde..f24785450f 100644 --- a/interface/resources/qml/controls-uit/Slider.qml +++ b/interface/resources/qml/controls-uit/Slider.qml @@ -8,9 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "../styles-uit" import "../controls-uit" as HifiControls @@ -26,63 +25,63 @@ Slider { height: hifi.fontSizes.textFieldInput + 14 // Match height of TextField control. y: sliderLabel.visible ? sliderLabel.height + sliderLabel.anchors.bottomMargin : 0 - style: SliderStyle { - groove: Rectangle { - implicitWidth: 50 - implicitHeight: hifi.dimensions.sliderGrooveHeight + background: Rectangle { + implicitWidth: 50 + implicitHeight: hifi.dimensions.sliderGrooveHeight + radius: height / 2 + color: isLightColorScheme ? hifi.colors.sliderGutterLight : hifi.colors.sliderGutterDark + + Rectangle { + width: parent.height - 2 + height: slider.width * (slider.value - slider.minimumValue) / (slider.maximumValue - slider.minimumValue) - 1 radius: height / 2 - color: isLightColorScheme ? hifi.colors.sliderGutterLight : hifi.colors.sliderGutterDark + anchors { + top: parent.top + topMargin: width + 1 + left: parent.left + leftMargin: 1 + } + transformOrigin: Item.TopLeft + rotation: -90 + gradient: Gradient { + GradientStop { position: 0.0; color: hifi.colors.blueAccent } + GradientStop { position: 1.0; color: hifi.colors.primaryHighlight } + } + } + } - Rectangle { - width: parent.height - 2 - height: slider.width * (slider.value - slider.minimumValue) / (slider.maximumValue - slider.minimumValue) - 1 - radius: height / 2 - anchors { - top: parent.top - topMargin: width + 1 - left: parent.left - leftMargin: 1 - } - transformOrigin: Item.TopLeft - rotation: -90 - gradient: Gradient { - GradientStop { position: 0.0; color: hifi.colors.blueAccent } - GradientStop { position: 1.0; color: hifi.colors.primaryHighlight } - } + handle: Rectangle { + x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width) + y: slider.topPadding + slider.availableHeight / 2 - height / 2 + implicitWidth: hifi.dimensions.sliderHandleSize + implicitHeight: hifi.dimensions.sliderHandleSize + radius: height / 2 + border.width: 1 + border.color: isLightColorScheme ? hifi.colors.sliderBorderLight : hifi.colors.sliderBorderDark + gradient: Gradient { + GradientStop { + position: 0.0 + color: pressed || hovered + ? (isLightColorScheme ? hifi.colors.sliderDarkStart : hifi.colors.sliderLightStart ) + : (isLightColorScheme ? hifi.colors.sliderLightStart : hifi.colors.sliderDarkStart ) + } + GradientStop { + position: 1.0 + color: pressed || hovered + ? (isLightColorScheme ? hifi.colors.sliderDarkFinish : hifi.colors.sliderLightFinish ) + : (isLightColorScheme ? hifi.colors.sliderLightFinish : hifi.colors.sliderDarkFinish ) } } - handle: Rectangle { - implicitWidth: hifi.dimensions.sliderHandleSize - implicitHeight: hifi.dimensions.sliderHandleSize + Rectangle { + height: parent.height - 2 + width: height radius: height / 2 + anchors.centerIn: parent + color: hifi.colors.transparent border.width: 1 - border.color: isLightColorScheme ? hifi.colors.sliderBorderLight : hifi.colors.sliderBorderDark - gradient: Gradient { - GradientStop { - position: 0.0 - color: pressed || hovered - ? (isLightColorScheme ? hifi.colors.sliderDarkStart : hifi.colors.sliderLightStart ) - : (isLightColorScheme ? hifi.colors.sliderLightStart : hifi.colors.sliderDarkStart ) - } - GradientStop { - position: 1.0 - color: pressed || hovered - ? (isLightColorScheme ? hifi.colors.sliderDarkFinish : hifi.colors.sliderLightFinish ) - : (isLightColorScheme ? hifi.colors.sliderLightFinish : hifi.colors.sliderDarkFinish ) - } - } - - Rectangle { - height: parent.height - 2 - width: height - radius: height / 2 - anchors.centerIn: parent - color: hifi.colors.transparent - border.width: 1 - border.color: hifi.colors.black - } + border.color: hifi.colors.black } } From b52163cb24908c9ec3062384b718d42dd4f79564 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 4 Dec 2017 20:54:35 +0100 Subject: [PATCH 020/109] Intitial SpinBox port --- .../resources/qml/controls-uit/SpinBox.qml | 159 ++++++++++++------ .../hifi/dialogs/attachments/Attachment.qml | 2 +- .../qml/hifi/dialogs/attachments/Vector3.qml | 8 +- 3 files changed, 108 insertions(+), 61 deletions(-) diff --git a/interface/resources/qml/controls-uit/SpinBox.qml b/interface/resources/qml/controls-uit/SpinBox.qml index a1237d4bc7..b4ad996554 100644 --- a/interface/resources/qml/controls-uit/SpinBox.qml +++ b/interface/resources/qml/controls-uit/SpinBox.qml @@ -8,9 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "../styles-uit" import "../controls-uit" as HifiControls @@ -19,11 +18,42 @@ SpinBox { id: spinBox property int colorScheme: hifi.colorSchemes.light - readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + readonly property bool isLightColorScheme: colorScheme === hifi.colorSchemes.light property string label: "" property string labelInside: "" property color colorLabelInside: hifi.colors.white property real controlHeight: height + (spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0) + property int decimals: 2; + property real factor: Math.pow(10, decimals) + + property real minimumValue: 0.0 + property real maximumValue: 0.0 + + property real realValue: 0.0 + property real realFrom: 0.0 + property real realTo: 100.0 + property real realStepSize: 1.0 + + locale: Qt.locale("en_US") + + onValueModified: { + realValue = value/factor + console.warn("rv (value mod)", realValue) + } + + onValueChanged: { + realValue = value/factor + console.warn("rv (value)", realValue) + } + + padding: 0 + leftPadding: 0 + rightPadding: 0 + + stepSize: realStepSize*factor + value: realValue*factor + to : realTo*factor + from : realFrom*factor FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } font.family: firaSansSemiBold.name @@ -32,43 +62,60 @@ SpinBox { y: spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0 - style: SpinBoxStyle { - id: spinStyle - background: Rectangle { - color: isLightColorScheme - ? (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGray) - : (spinBox.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow) - border.color: spinBoxLabelInside.visible ? spinBoxLabelInside.color : hifi.colors.primaryHighlight - border.width: spinBox.activeFocus ? spinBoxLabelInside.visible ? 2 : 1 : 0 - } + background: Rectangle { + color: isLightColorScheme + ? (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGray) + : (spinBox.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow) + border.color: spinBoxLabelInside.visible ? spinBoxLabelInside.color : hifi.colors.primaryHighlight + border.width: spinBox.activeFocus ? spinBoxLabelInside.visible ? 2 : 1 : 0 + } - textColor: isLightColorScheme - ? (spinBox.activeFocus ? hifi.colors.black : hifi.colors.lightGray) - : (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGrayText) + validator: DoubleValidator { + bottom: Math.min(spinBox.from, spinBox.to)*spinBox.factor + top: Math.max(spinBox.from, spinBox.to)*spinBox.factor + } + + textFromValue: function(value, locale) { + return parseFloat(value*1.0/factor).toFixed(decimals); + } + + valueFromText: function(text, locale) { + console.warn("valueFromText", text) + return Number.fromLocaleString(locale, text); + } + + + contentItem: TextInput { + color: isLightColorScheme + ? (spinBox.activeFocus ? hifi.colors.black : hifi.colors.lightGray) + : (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGrayText) selectedTextColor: hifi.colors.black selectionColor: hifi.colors.primaryHighlight + text: spinBox.textFromValue(spinBox.value, spinBox.locale) + verticalAlignment: Qt.AlignVCenter + leftPadding: spinBoxLabelInside.visible ? 30 : hifi.dimensions.textPadding + //rightPadding: hifi.dimensions.spinnerSize + width: spinBox.width - hifi.dimensions.spinnerSize + } - horizontalAlignment: Qt.AlignLeft - padding.left: spinBoxLabelInside.visible ? 30 : hifi.dimensions.textPadding - padding.right: hifi.dimensions.spinnerSize - padding.top: 0 + up.indicator: HiFiGlyphs { + x: spinBox.mirrored ? 0 : spinBox.width - implicitWidth + 10 + y: 1 + height: parent.height/2 + width: height + text: hifi.glyphs.caratUp + size: hifi.dimensions.spinnerSize + color: spinBox.up.pressed || spinBox.up.hovered ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray + } - incrementControl: HiFiGlyphs { - id: incrementButton - text: hifi.glyphs.caratUp - x: 10 - y: 1 - size: hifi.dimensions.spinnerSize - color: styleData.upPressed ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray - } - - decrementControl: HiFiGlyphs { + down.indicator: HiFiGlyphs { + x: spinBox.mirrored ? 0 : spinBox.width - implicitWidth + 10 + height: parent.height/2 + width: height + y: height - 1 text: hifi.glyphs.caratDn - x: 10 - y: -1 size: hifi.dimensions.spinnerSize - color: styleData.downPressed ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray - } + color: spinBox.down.pressed || spinBox.up.hovered ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray } HifiControls.Label { @@ -92,26 +139,26 @@ SpinBox { visible: spinBox.labelInside != "" } - MouseArea { - anchors.fill: parent - propagateComposedEvents: true - onWheel: { - if(spinBox.activeFocus) - wheel.accepted = false - else - wheel.accepted = true - } - onPressed: { - mouse.accepted = false - } - onReleased: { - mouse.accepted = false - } - onClicked: { - mouse.accepted = false - } - onDoubleClicked: { - mouse.accepted = false - } - } +// MouseArea { +// anchors.fill: parent +// propagateComposedEvents: true +// onWheel: { +// if(spinBox.activeFocus) +// wheel.accepted = false +// else +// wheel.accepted = true +// } +// onPressed: { +// mouse.accepted = false +// } +// onReleased: { +// mouse.accepted = false +// } +// onClicked: { +// mouse.accepted = false +// } +// onDoubleClicked: { +// mouse.accepted = false +// } +// } } diff --git a/interface/resources/qml/hifi/dialogs/attachments/Attachment.qml b/interface/resources/qml/hifi/dialogs/attachments/Attachment.qml index 89ad327a71..d93e077b5a 100644 --- a/interface/resources/qml/hifi/dialogs/attachments/Attachment.qml +++ b/interface/resources/qml/hifi/dialogs/attachments/Attachment.qml @@ -180,7 +180,7 @@ Item { decimals: 2; minimumValue: 0.01 maximumValue: 10 - stepSize: 0.05; + realStepSize: 0.05; value: attachment ? attachment.scale : 1.0 colorScheme: hifi.colorSchemes.dark onValueChanged: { diff --git a/interface/resources/qml/hifi/dialogs/attachments/Vector3.qml b/interface/resources/qml/hifi/dialogs/attachments/Vector3.qml index eb6172ec78..228d71fe6f 100644 --- a/interface/resources/qml/hifi/dialogs/attachments/Vector3.qml +++ b/interface/resources/qml/hifi/dialogs/attachments/Vector3.qml @@ -56,12 +56,12 @@ Item { colorScheme: hifi.colorSchemes.dark colorLabelInside: hifi.colors.redHighlight decimals: root.decimals - stepSize: root.stepSize + realStepSize: root.stepSize maximumValue: root.maximumValue minimumValue: root.minimumValue - onValueChanged: { - if (value !== vector.x) { - vector.x = value + onRealValueChanged: { + if (realValue !== vector.x) { + vector.x = realValue root.valueChanged(); } } From 1cf82b7725c1eecdfa38fa6f8296c476c456df79 Mon Sep 17 00:00:00 2001 From: vladest Date: Tue, 19 Dec 2017 21:28:28 +0100 Subject: [PATCH 021/109] SpinBox now works --- .../resources/qml/controls-uit/SpinBox.qml | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/interface/resources/qml/controls-uit/SpinBox.qml b/interface/resources/qml/controls-uit/SpinBox.qml index b4ad996554..32da3a6df8 100644 --- a/interface/resources/qml/controls-uit/SpinBox.qml +++ b/interface/resources/qml/controls-uit/SpinBox.qml @@ -34,6 +34,15 @@ SpinBox { property real realTo: 100.0 property real realStepSize: 1.0 + implicitHeight: height + implicitWidth: width + + padding: 0 + leftPadding: 0 + rightPadding: padding + (up.indicator ? up.indicator.width : 0) + topPadding: 0 + bottomPadding: 0 + locale: Qt.locale("en_US") onValueModified: { @@ -46,10 +55,6 @@ SpinBox { console.warn("rv (value)", realValue) } - padding: 0 - leftPadding: 0 - rightPadding: 0 - stepSize: realStepSize*factor value: realValue*factor to : realTo*factor @@ -86,6 +91,7 @@ SpinBox { contentItem: TextInput { + z: 2 color: isLightColorScheme ? (spinBox.activeFocus ? hifi.colors.black : hifi.colors.lightGray) : (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGrayText) @@ -97,25 +103,32 @@ SpinBox { //rightPadding: hifi.dimensions.spinnerSize width: spinBox.width - hifi.dimensions.spinnerSize } - - up.indicator: HiFiGlyphs { - x: spinBox.mirrored ? 0 : spinBox.width - implicitWidth + 10 + up.indicator: Item { + x: spinBox.width - implicitWidth - 5 y: 1 - height: parent.height/2 - width: height - text: hifi.glyphs.caratUp - size: hifi.dimensions.spinnerSize - color: spinBox.up.pressed || spinBox.up.hovered ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray - } - - down.indicator: HiFiGlyphs { - x: spinBox.mirrored ? 0 : spinBox.width - implicitWidth + 10 - height: parent.height/2 - width: height - y: height - 1 - text: hifi.glyphs.caratDn + clip: true + implicitHeight: spinBox.implicitHeight/2 + implicitWidth: spinBox.implicitHeight/2 + HiFiGlyphs { + anchors.centerIn: parent + text: hifi.glyphs.caratUp size: hifi.dimensions.spinnerSize color: spinBox.down.pressed || spinBox.up.hovered ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray + } + } + + down.indicator: Item { + x: spinBox.width - implicitWidth - 5 + y: spinBox.implicitHeight/2 + clip: true + implicitHeight: spinBox.implicitHeight/2 + implicitWidth: spinBox.implicitHeight/2 + HiFiGlyphs { + anchors.centerIn: parent + text: hifi.glyphs.caratDn + size: hifi.dimensions.spinnerSize + color: spinBox.down.pressed || spinBox.down.hovered ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray + } } HifiControls.Label { From 5877eeea0b85a99ea9f402396006265da4bdbb18 Mon Sep 17 00:00:00 2001 From: vladest Date: Tue, 19 Dec 2017 21:35:11 +0100 Subject: [PATCH 022/109] cleanup --- interface/resources/qml/controls-uit/SpinBox.qml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/controls-uit/SpinBox.qml b/interface/resources/qml/controls-uit/SpinBox.qml index 32da3a6df8..a04441851f 100644 --- a/interface/resources/qml/controls-uit/SpinBox.qml +++ b/interface/resources/qml/controls-uit/SpinBox.qml @@ -45,15 +45,8 @@ SpinBox { locale: Qt.locale("en_US") - onValueModified: { - realValue = value/factor - console.warn("rv (value mod)", realValue) - } - - onValueChanged: { - realValue = value/factor - console.warn("rv (value)", realValue) - } + onValueModified: realValue = value/factor + onValueChanged: realValue = value/factor stepSize: realStepSize*factor value: realValue*factor @@ -85,7 +78,6 @@ SpinBox { } valueFromText: function(text, locale) { - console.warn("valueFromText", text) return Number.fromLocaleString(locale, text); } From f5f19ea67fb1a978be0bd3db7fe208ee939483e6 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 28 Dec 2017 15:53:16 +0100 Subject: [PATCH 023/109] Move RadioButton --- .../qml/controls-uit/RadioButton.qml | 8 ++++++-- interface/resources/qml/js/Utils.jsc | Bin 6596 -> 6274 bytes 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/controls-uit/RadioButton.qml b/interface/resources/qml/controls-uit/RadioButton.qml index bc6426977d..ebfe1ff9a9 100644 --- a/interface/resources/qml/controls-uit/RadioButton.qml +++ b/interface/resources/qml/controls-uit/RadioButton.qml @@ -36,7 +36,7 @@ Original.RadioButton { onHoveredChanged: { if (hovered) { - tabletInterface.playSound(TabletEnums.ButtonHover); + Tablet.playSound(TabletEnums.ButtonHover); } } @@ -45,6 +45,8 @@ Original.RadioButton { width: boxSize height: boxSize radius: 7 + x: radioButton.leftPadding + y: parent.height / 2 - height / 2 gradient: Gradient { GradientStop { position: 0.2 @@ -77,6 +79,8 @@ Original.RadioButton { text: radioButton.text size: hifi.fontSizes.inputLabel color: isLightColorScheme ? hifi.colors.lightGray : hifi.colors.lightGrayText - x: radioButton.boxSize / 2 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + leftPadding: radioButton.indicator.width + radioButton.spacing } } diff --git a/interface/resources/qml/js/Utils.jsc b/interface/resources/qml/js/Utils.jsc index ab20e996b9469915ac6a89901da175143e6b5024..eded46b485e5e9b6b6bb8f6c731dee09de5b40b5 100644 GIT binary patch literal 6274 zcmcIoUu;`f8UNYW85s<27+V>vj0!Ggsz$w`YMM}`#hEi~aHhbrsGUaFEOC~U{9EEy z=~N(H8WhV^_+hFH;=vD<=7&D`VL~PpD?mjj;Gx~R(N24qrcFww2xS(3sxfBtJLfys z_qx|fqli;gC-*zw{r>*G?|j$K9osiJG>{qi902RqHYDo#olk~<6K%k`zkINN;YSar zfAhw#FLv$z{O&ISxCb|`uLJlpfCFKm4M1L4&Nl63c{ckOTJtxKQKJ9TnVh6T8C`!sn&xm!7bL!vMVUrkukhWri9F-` zl`!yD82Bg*++hLxEFf+HeHJie0T~N8VF9Ns;Aa+a)&gF(fb$k`!236xPLJ&0mc38*UfH{4 ze^T~?=u+~gF^QupGCEH5FNH}AVgO@E<8fp#t!#c)*|$qD?TzPQ6~9r%|1Ct-zY!Jb zG@=-DrA5(?NAL(9LpS;m#WBn%U&d6FeuyZBkXD}aohghXjR|BB#Rx_*to}1g;w_PgKkcu_b~wnTe+mIhs;W2QDw0d}sExRuCl|ZqhFpCiFGH0U zYP;_D+O;=CpW;p>dAiT3R4G++Ey80xuZ4!PD*XtM^^S^x^Gk zL!-~GDZi|S^*&kO@ylvN!Y9k2EH~T9`L$kVHkCWNlFE&*r*i4*iTMk?Klo#VXZ3IO zdfnt4TgMZdWH6q3ayxo*-*2zQ?2fLETFm}z+^KkJcWGMLOWUPsrJmf5*u}2<8T~5T zmrg;+o6i48K#Hvx-V}yH>|)%xfL#{&$1<~!%*CAo5%UVIi#rvq_L6=o>!+(k({h#7 ztpe z0qO?+y&&3dq6Ykd6tz-b9F|nBJmtj?0#6N`T$=;1X&GE$Bil0mcPL#!_o25hN&hNp z+P%qKIFai-OdAV6(g;a;A8CrDMIULFq&Y8Xjvgknr<_?{#;S2@C39@=JeX=e;8zk4 zMw$-_a&Wl$fQ7|34(J0mSWfLa;gTaJrz38_zU%|LG|M?pS!jbjm7xul;^5obKuuWD z1RACZ>zY7=G~s$;$rPen%F-5ky*K_;gs#M$LgOMEPS_LDz>8W~emG(O_)_YD6>=84 zbA8T>v6CP2BCr?u`BRJ8d-|OGYA1l$??1d<%{aRmq|+yye5`(^9QKS4|FwYB11n0+ z>Zi$-i#vHkF?QrT$?!_eK6E)z`QhV8wV?VrA+n%nj)nc1o(w6rLeUNx4k zYqM(hfotA4;QYmRvdHcSQyt{tV#vie=$N+%hAuEZ{El z8Y)%U%bI)XqjGiln$jFcM23fbiAm;9GnBE&dn&K*&Sh`GaYW<`d2$uWRnT1g!NtAv zt_fFDvDpH8UZHzlT_vJSy`4J5SG<+P_@8y_)V#`)-t&(C)vwB{2HJ1e>;qT4z$mWj zY8H#dFaAX1T5PVGqNExfp2l>Oyd@E;RS*Ye5~d zV0yI|B8Bai`$Ui`_gWyTjNYp?yW`L7t~L89U(qWY8jx?eTMTx$*zE56LEY0-MY9bD zU-SBJ0HDy+;!7)MW^e%uAsh@A{Y}*xEHNX=onwQ*a<_0brrjX0{L@U%%;3ubU?~Sj zuiPBHb3qNe90Zm!RhU8EkM2n zXjl7O2dDtRuNCd{@)jY-)d!#zenqKY4sn&W{weu)twmlb!$4JTzv65rm+K1vDC#!F zU$|ZVIZ9zlW+S<`HL;hgR&M8~1sQiLyXg~6*Kx4qHtya=?){4Iz`gR%B^6)FqD(EX zPx0NgjXdr9YAbNP75KOnxYqy<89DFo`<=jA05hh+!CUJc)7q5K-I-U<4BwMhw#!Kold03qHB1qPh=(m57jV zQZO*TlsKpO<^4D&)ji|-UBpF<$-`KmCFTK~acFxKqv8qb`vJ}(jwnv6ynF{ogq(=F zep_Ap)wNGud)4)O>UtbUguEF{VOB&&#)x21=BI^yoeI;=cpet< z8yEavN0<0LF8)1^DU2eDE}X7EzTC=9#(VVvU%?VLXPX@E8u^tC$cdhzrY~ z5|TzSE|9{#2}}z<=It55SzSj%iNA*yHv6nZbjwP_N>*aF82-K7|F|4Z{3((gYY*l1 z1HmPNES&HK!VAmo!G#Z7%nSc2m&=jFSbJz;vopy0hR~Acw-O%(%P$^o0YVGQoxRBc zfA58N%nJ{-l0bHGCbwg^#q(qrrDi+!w<_$cdfT#JQtVa6B|0HZKTvD>SPT8{3FK*i zWU(iZU!oSteUbW{j!MrrowDh%hwMA*Wz%5~+1G_Km+UHco!!3?d2`uawWQAO`Fhz^ zFY9DKQ7^k1!8+Li%B~H>BZmbX7dAVWSkh#gI3&0r zaF0rAW;@0YRTR^~w|fH1=rq7T1!gIn>dAFt!Sy*C45#|hZ zyKMQfPE=zR8BZ12Iu&e;jZ`qZ;(XBNe0X7VdI#CX&hyK$=>L{qIw{h|R_2l4RI7AY z^-G-Fg*Pl@c)U6&I`)6~vWKqD3?b!JxCu1uN`cA?Q-i-75ra?*w4> z7DLeZEXfck*xy13exhOT)~XM$^JKYWuGBjYFUK{J-kQV9*AmCcI=9Ipz3t&zt&~o& zbp5o=j@d0M5iMDXSkX$%t~YJ^dxYvnP2X7@RT0fd+JSJgHI(cgqRD9&=_E-h7ipTL zi!Ra}N%Kz9JRJ@v&Ijf=afs?ImCUopaAUf5Bc(P@)^4QL#!&4B4=hC;lN+q^_W+Q1 zP^n|i{5|@(6kNweRp@!g!IB0$&XzP(9WOq8UKl6|MM0Czbbp-MJtdAmS4|C?43SDf)z9}dNlLtGo5xl*UM-i)V9TyEvOFWw5I(m_-&8|fx011{`>NNH;(6Df(rr#QsN>-}$CJna|wOpzoRcq-Fq`bAH8fghvwNyJ`N_RlpJYiGQZuHu}HZ5Pa zdE8c|q5`8P==g;$uId?L_>-ZdTT7Ja(9^jWIyw}4%`oqUj`vkn%QKo+>hkt%Am^R8 zT%)}GyrqJUtqMAFDsNlV@ Date: Sat, 30 Dec 2017 19:55:52 +0100 Subject: [PATCH 024/109] TextField moved. Fixed sound on hovering check box --- .../resources/qml/controls-uit/CheckBox.qml | 2 +- .../resources/qml/controls-uit/TextField.qml | 142 ++++++++++-------- interface/resources/qml/js/Utils.jsc | Bin 6274 -> 0 bytes 3 files changed, 79 insertions(+), 65 deletions(-) delete mode 100644 interface/resources/qml/js/Utils.jsc diff --git a/interface/resources/qml/controls-uit/CheckBox.qml b/interface/resources/qml/controls-uit/CheckBox.qml index 208e5cc965..997f22bcbb 100644 --- a/interface/resources/qml/controls-uit/CheckBox.qml +++ b/interface/resources/qml/controls-uit/CheckBox.qml @@ -36,7 +36,7 @@ Original.CheckBox { onHoveredChanged: { if (hovered) { - tabletInterface.playSound(TabletEnums.ButtonHover); + Tablet.playSound(TabletEnums.ButtonHover); } } diff --git a/interface/resources/qml/controls-uit/TextField.qml b/interface/resources/qml/controls-uit/TextField.qml index e636bfc27f..cf5bd40173 100644 --- a/interface/resources/qml/controls-uit/TextField.qml +++ b/interface/resources/qml/controls-uit/TextField.qml @@ -8,9 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "../styles-uit" import "../controls-uit" as HifiControls @@ -27,8 +26,7 @@ TextField { property bool hasRoundedBorder: false property bool error: false; property bool hasClearButton: false; - - placeholderText: textField.placeholderText + property alias textColor: textField.color FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } font.family: firaSansSemiBold.name @@ -42,41 +40,56 @@ TextField { // workaround for https://bugreports.qt.io/browse/QTBUG-49297 Keys.onPressed: { switch (event.key) { - case Qt.Key_Return: - case Qt.Key_Enter: - event.accepted = true; + case Qt.Key_Return: + case Qt.Key_Enter: + event.accepted = true; - // emit accepted signal manually - if (acceptableInput) { - accepted(); - } + // emit accepted signal manually + if (acceptableInput) { + accepted(); + } } } - style: TextFieldStyle { - textColor: { - if (isLightColorScheme) { - if (textField.activeFocus) { - hifi.colors.black - } else { - hifi.colors.lightGray - } - } else if (isFaintGrayColorScheme) { - if (textField.activeFocus) { - hifi.colors.black - } else { - hifi.colors.lightGray - } + Text { + id: placeholder + x: textField.leftPadding + y: textField.topPadding + width: textField.width - (textField.leftPadding + textField.rightPadding) + height: textField.height - (textField.topPadding + textField.bottomPadding) + + text: textField.placeholderText + font: textField.font + color: textField.placeholderTextColor + verticalAlignment: textField.verticalAlignment + visible: !textField.length && !textField.preeditText && (!textField.activeFocus || textField.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + } + + color: { + if (isLightColorScheme) { + if (textField.activeFocus) { + hifi.colors.black } else { - if (textField.activeFocus) { - hifi.colors.white - } else { - hifi.colors.lightGrayText - } + hifi.colors.lightGray + } + } else if (isFaintGrayColorScheme) { + if (textField.activeFocus) { + hifi.colors.black + } else { + hifi.colors.lightGray + } + } else { + if (textField.activeFocus) { + hifi.colors.white + } else { + hifi.colors.lightGrayText } } - background: Rectangle { - color: { + } + + background: Rectangle { + color: { if (isLightColorScheme) { if (textField.activeFocus) { hifi.colors.white @@ -97,45 +110,46 @@ TextField { } } } - border.color: textField.error ? hifi.colors.redHighlight : - (textField.activeFocus ? hifi.colors.primaryHighlight : (isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray)) - border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0 - radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? 4 : 0) + border.color: textField.error ? hifi.colors.redHighlight : + (textField.activeFocus ? hifi.colors.primaryHighlight : (isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray)) + border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0 + radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? 4 : 0) - HiFiGlyphs { - text: hifi.glyphs.search - color: textColor - size: hifi.fontSizes.textFieldSearchIcon - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: hifi.dimensions.textPadding - 2 - visible: isSearchField - } + HiFiGlyphs { + text: hifi.glyphs.search + color: textColor + size: hifi.fontSizes.textFieldSearchIcon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: hifi.dimensions.textPadding - 2 + visible: isSearchField + } - HiFiGlyphs { - text: hifi.glyphs.error - color: textColor - size: 40 - anchors.right: parent.right - anchors.rightMargin: hifi.dimensions.textPadding - 2 - anchors.verticalCenter: parent.verticalCenter - visible: hasClearButton && textField.text !== ""; + HiFiGlyphs { + text: hifi.glyphs.error + color: textColor + size: 40 + anchors.right: parent.right + anchors.rightMargin: hifi.dimensions.textPadding - 2 + anchors.verticalCenter: parent.verticalCenter + visible: hasClearButton && textField.text !== ""; - MouseArea { - anchors.fill: parent; - onClicked: { - textField.text = ""; - } + MouseArea { + anchors.fill: parent; + onClicked: { + textField.text = ""; } } } - placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray - selectedTextColor: hifi.colors.black - selectionColor: hifi.colors.primaryHighlight - padding.left: (isSearchField ? textField.height - 2 : 0) + hifi.dimensions.textPadding - padding.right: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding } + property color placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray + selectedTextColor: hifi.colors.black + selectionColor: hifi.colors.primaryHighlight + leftPadding: (isSearchField ? textField.height - 2 : 0) + hifi.dimensions.textPadding + rightPadding: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding + + HifiControls.Label { id: textFieldLabel text: textField.label diff --git a/interface/resources/qml/js/Utils.jsc b/interface/resources/qml/js/Utils.jsc deleted file mode 100644 index eded46b485e5e9b6b6bb8f6c731dee09de5b40b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6274 zcmcIoUu;`f8UNYW85s<27+V>vj0!Ggsz$w`YMM}`#hEi~aHhbrsGUaFEOC~U{9EEy z=~N(H8WhV^_+hFH;=vD<=7&D`VL~PpD?mjj;Gx~R(N24qrcFww2xS(3sxfBtJLfys z_qx|fqli;gC-*zw{r>*G?|j$K9osiJG>{qi902RqHYDo#olk~<6K%k`zkINN;YSar zfAhw#FLv$z{O&ISxCb|`uLJlpfCFKm4M1L4&Nl63c{ckOTJtxKQKJ9TnVh6T8C`!sn&xm!7bL!vMVUrkukhWri9F-` zl`!yD82Bg*++hLxEFf+HeHJie0T~N8VF9Ns;Aa+a)&gF(fb$k`!236xPLJ&0mc38*UfH{4 ze^T~?=u+~gF^QupGCEH5FNH}AVgO@E<8fp#t!#c)*|$qD?TzPQ6~9r%|1Ct-zY!Jb zG@=-DrA5(?NAL(9LpS;m#WBn%U&d6FeuyZBkXD}aohghXjR|BB#Rx_*to}1g;w_PgKkcu_b~wnTe+mIhs;W2QDw0d}sExRuCl|ZqhFpCiFGH0U zYP;_D+O;=CpW;p>dAiT3R4G++Ey80xuZ4!PD*XtM^^S^x^Gk zL!-~GDZi|S^*&kO@ylvN!Y9k2EH~T9`L$kVHkCWNlFE&*r*i4*iTMk?Klo#VXZ3IO zdfnt4TgMZdWH6q3ayxo*-*2zQ?2fLETFm}z+^KkJcWGMLOWUPsrJmf5*u}2<8T~5T zmrg;+o6i48K#Hvx-V}yH>|)%xfL#{&$1<~!%*CAo5%UVIi#rvq_L6=o>!+(k({h#7 ztpe z0qO?+y&&3dq6Ykd6tz-b9F|nBJmtj?0#6N`T$=;1X&GE$Bil0mcPL#!_o25hN&hNp z+P%qKIFai-OdAV6(g;a;A8CrDMIULFq&Y8Xjvgknr<_?{#;S2@C39@=JeX=e;8zk4 zMw$-_a&Wl$fQ7|34(J0mSWfLa;gTaJrz38_zU%|LG|M?pS!jbjm7xul;^5obKuuWD z1RACZ>zY7=G~s$;$rPen%F-5ky*K_;gs#M$LgOMEPS_LDz>8W~emG(O_)_YD6>=84 zbA8T>v6CP2BCr?u`BRJ8d-|OGYA1l$??1d<%{aRmq|+yye5`(^9QKS4|FwYB11n0+ z>Zi$-i#vHkF?QrT$?!_eK6E)z`QhV8wV?VrA+n%nj)nc1o(w6rLeUNx4k zYqM(hfotA4;QYmRvdHcSQyt{tV#vie=$N+%hAuEZ{El z8Y)%U%bI)XqjGiln$jFcM23fbiAm;9GnBE&dn&K*&Sh`GaYW<`d2$uWRnT1g!NtAv zt_fFDvDpH8UZHzlT_vJSy`4J5SG<+P_@8y_)V#`)-t&(C)vwB{2HJ1e>;qT4z$mWj zY8H#dFaAX1T5PVGqNExfp2l>Oyd@E;RS*Ye5~d zV0yI|B8Bai`$Ui`_gWyTjNYp?yW`L7t~L89U(qWY8jx?eTMTx$*zE56LEY0-MY9bD zU-SBJ0HDy+;!7)MW^e%uAsh@A{Y}*xEHNX=onwQ*a<_0brrjX0{L@U%%;3ubU?~Sj zuiPBHb3qNe90Zm!Rh Date: Sun, 31 Dec 2017 15:17:44 +0100 Subject: [PATCH 025/109] Switch moved --- .../resources/qml/controls-uit/Switch.qml | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/interface/resources/qml/controls-uit/Switch.qml b/interface/resources/qml/controls-uit/Switch.qml index d54f986717..bfe86b1420 100644 --- a/interface/resources/qml/controls-uit/Switch.qml +++ b/interface/resources/qml/controls-uit/Switch.qml @@ -8,9 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 as Original -import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 as Original import "../styles-uit" @@ -33,44 +32,49 @@ Item { Original.Switch { id: originalSwitch; - activeFocusOnPress: true; + focusPolicy: Qt.ClickFocus anchors.top: rootSwitch.top; anchors.left: rootSwitch.left; anchors.leftMargin: rootSwitch.width/2 - rootSwitch.switchWidth/2; onCheckedChanged: rootSwitch.onCheckedChanged(); onClicked: rootSwitch.clicked(); + hoverEnabled: true - style: SwitchStyle { + topPadding: 3; + leftPadding: 3; + rightPadding: 3; + bottomPadding: 3; - padding { - top: 3; - left: 3; - right: 3; - bottom: 3; + onHoveredChanged: { + if (hovered) { + switchHandle.color = hifi.colors.blueHighlight; + } else { + switchHandle.color = hifi.colors.lightGray; + } + } + + background: Rectangle { + color: "#252525"; + implicitWidth: rootSwitch.switchWidth; + implicitHeight: rootSwitch.height; + radius: rootSwitch.switchRadius; + } + + indicator: Rectangle { + id: switchHandle; + implicitWidth: rootSwitch.height - originalSwitch.topPadding - originalSwitch.bottomPadding; + implicitHeight: implicitWidth; + radius: implicitWidth/2; + border.color: hifi.colors.lightGrayText; + color: hifi.colors.lightGray; + //x: originalSwitch.leftPadding + x: Math.max(0, Math.min(parent.width - width, originalSwitch.visualPosition * parent.width - (width / 2))) + y: parent.height / 2 - height / 2 + Behavior on x { + enabled: !originalSwitch.down + SmoothedAnimation { velocity: 200 } } - groove: Rectangle { - color: "#252525"; - implicitWidth: rootSwitch.switchWidth; - implicitHeight: rootSwitch.height; - radius: rootSwitch.switchRadius; - } - - handle: Rectangle { - id: switchHandle; - implicitWidth: rootSwitch.height - padding.top - padding.bottom; - implicitHeight: implicitWidth; - radius: implicitWidth/2; - border.color: hifi.colors.lightGrayText; - color: hifi.colors.lightGray; - - MouseArea { - anchors.fill: parent; - hoverEnabled: true; - onEntered: parent.color = hifi.colors.blueHighlight; - onExited: parent.color = hifi.colors.lightGray; - } - } } } From 45144bece6d429a609b1ea0fc01884ef2328b5f5 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 11 Jan 2018 22:05:11 +0100 Subject: [PATCH 026/109] Fix Properties does not fit in Create tab --- interface/resources/qml/hifi/tablet/EditTabButton.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/tablet/EditTabButton.qml b/interface/resources/qml/hifi/tablet/EditTabButton.qml index 761ab4d8cd..666ea16927 100644 --- a/interface/resources/qml/hifi/tablet/EditTabButton.qml +++ b/interface/resources/qml/hifi/tablet/EditTabButton.qml @@ -24,7 +24,7 @@ TabButton { contentItem: Text { id: text text: control.text - font.pixelSize: 16 + font.pixelSize: 14 font.bold: true color: control.checked ? "white" : "white" horizontalAlignment: Text.AlignHCenter From e7a035f954ed16f58583c086bea1005dd515b9eb Mon Sep 17 00:00:00 2001 From: vladest Date: Fri, 19 Jan 2018 23:01:41 +0100 Subject: [PATCH 027/109] Fix indent --- .../resources/qml/controls-uit/TextField.qml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/interface/resources/qml/controls-uit/TextField.qml b/interface/resources/qml/controls-uit/TextField.qml index ffc2995f01..814c07cb8a 100644 --- a/interface/resources/qml/controls-uit/TextField.qml +++ b/interface/resources/qml/controls-uit/TextField.qml @@ -118,16 +118,16 @@ TextField { radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? 4 : 0) HiFiGlyphs { - text: textField.leftPlaceholderGlyph; - color: textColor; - size: hifi.fontSizes.textFieldSearchIcon; - anchors.left: parent.left; - anchors.verticalCenter: parent.verticalCenter; - anchors.leftMargin: hifi.dimensions.textPadding - 2; - visible: text; - } + text: textField.leftPlaceholderGlyph; + color: textColor; + size: hifi.fontSizes.textFieldSearchIcon; + anchors.left: parent.left; + anchors.verticalCenter: parent.verticalCenter; + anchors.leftMargin: hifi.dimensions.textPadding - 2; + visible: text; + } - HiFiGlyphs { + HiFiGlyphs { text: hifi.glyphs.search color: textColor size: hifi.fontSizes.textFieldSearchIcon From 7d7c3bb1f57480acfbb7cd8ec6cf80332caa891f Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 22 Feb 2018 10:30:42 +0100 Subject: [PATCH 028/109] Change new material dialog to QQC2 --- interface/resources/qml/hifi/tablet/NewMaterialDialog.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/NewMaterialDialog.qml b/interface/resources/qml/hifi/tablet/NewMaterialDialog.qml index 226c17e8e2..e49d78193b 100644 --- a/interface/resources/qml/hifi/tablet/NewMaterialDialog.qml +++ b/interface/resources/qml/hifi/tablet/NewMaterialDialog.qml @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import QtQuick.Dialogs 1.2 as OriginalDialogs import "../../styles-uit" From 931696322f192080ecdc92fc0c90bf6523caf7b7 Mon Sep 17 00:00:00 2001 From: vladest Date: Sun, 25 Feb 2018 08:58:05 +0100 Subject: [PATCH 029/109] Fixed stucked mouse pointer in QQC2 toolbar mode --- interface/resources/qml/windows/ScrollingWindow.qml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 1966380709..8e71064195 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -38,14 +38,14 @@ Window { property bool keyboardRaised: false property bool punctuationMode: false + // Scrollable window content. // FIXME this should not define any visual content in this type. The base window // type should only consist of logic sized areas, with nothing drawn (although the // default value for the frame property does include visual decorations) property var pane: Item { - property bool isScrolling: scrollView.contentChildren.length > 0 ? - (scrollView.height < scrollView.contentChildren[0].height) : - false + property bool isScrolling: scrollView.height < scrollView.contentItem.height + property int contentWidth: scrollView.width - (isScrolling ? 10 : 0) property int scrollHeight: scrollView.height @@ -60,7 +60,6 @@ Window { visible: !window.hideBackground && modality != Qt.ApplicationModal } - LinearGradient { visible: !window.hideBackground && gradientsSupported && modality != Qt.ApplicationModal anchors.top: contentBackground.bottom @@ -78,9 +77,9 @@ Window { ScrollView { id: scrollView - contentChildren: content - clip: true + contentItem: content ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + anchors.fill: parent anchors.rightMargin: parent.isScrolling ? 1 : 0 anchors.bottomMargin: footerPane.height @@ -120,8 +119,6 @@ Window { } } } - - } function scrollBy(delta) { From b7f146fd473363507ab36c33c1f2c28d42b1ba19 Mon Sep 17 00:00:00 2001 From: vladest Date: Tue, 27 Feb 2018 16:27:08 +0100 Subject: [PATCH 030/109] Fix clipping issues in scrolling window --- interface/resources/qml/windows/ScrollingWindow.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 8e71064195..94cab7fd29 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -79,6 +79,7 @@ Window { id: scrollView contentItem: content ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + clip: true anchors.fill: parent anchors.rightMargin: parent.isScrolling ? 1 : 0 From 90b891dbc3d4db70ba5950f39b56100310a6ae06 Mon Sep 17 00:00:00 2001 From: vladest Date: Tue, 27 Feb 2018 16:42:30 +0100 Subject: [PATCH 031/109] Fix push issue due to merge errors --- interface/resources/qml/hifi/tablet/Edit.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/Edit.qml b/interface/resources/qml/hifi/tablet/Edit.qml index 3b440e9e22..8e362b8b78 100644 --- a/interface/resources/qml/hifi/tablet/Edit.qml +++ b/interface/resources/qml/hifi/tablet/Edit.qml @@ -22,8 +22,7 @@ ColumnLayout { signal sendToScript(var message); function pushSource(path) { - editRoot.push(Qt.resolvedUrl("../../" + path)); - editStack.push(Qt.resolvedUrl(path)); + editStack.push(Qt.resolvedUrl("../../" + path)); editStack.currentItem.sendToScript.connect(editRoot.sendToScript); } From 7cbdbe9ab01b98a1a674bee1c439ef5b56accd8e Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 1 Mar 2018 11:02:05 +0100 Subject: [PATCH 032/109] Make Edit view more consistant with original one --- interface/resources/qml/hifi/tablet/Edit.qml | 299 +---------- .../qml/hifi/tablet/EditTabButton.qml | 9 +- .../resources/qml/hifi/tablet/EditTabView.qml | 480 ++++++++---------- .../hifi/tablet/TabletGraphicsPreferences.qml | 4 +- 4 files changed, 259 insertions(+), 533 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/Edit.qml b/interface/resources/qml/hifi/tablet/Edit.qml index 8e362b8b78..28d6094194 100644 --- a/interface/resources/qml/hifi/tablet/Edit.qml +++ b/interface/resources/qml/hifi/tablet/Edit.qml @@ -6,289 +6,42 @@ import "../../controls-uit" as HifiControls import "../../controls" import "../toolbars" -ColumnLayout { +StackView { id: editRoot objectName: "stack" - anchors.fill: parent + //anchors.fill: parent + topPadding: 40 - readonly property var webTabsLinks: [ - "", - "/system/html/entityList.html", - "/system/html/entityProperties.html", - "/system/html/gridControls.html", - "/system/particle_explorer/particleExplorer.html" - ] + property var itemProperties: {"y": editRoot.topPadding, + "width": editRoot.availableWidth, + "height": editRoot.availableHeight } + Component.onCompleted: { + tab.currentIndex = 0 + } + + background: Rectangle { + color: "#404040" //default background color + EditTabView { + id: tab + currentIndex: -1 + onCurrentIndexChanged: { + editRoot.replace(null, tab.itemAt(currentIndex).visualItem, + itemProperties, + StackView.Immediate) + } + } + } signal sendToScript(var message); function pushSource(path) { - editStack.push(Qt.resolvedUrl("../../" + path)); - editStack.currentItem.sendToScript.connect(editRoot.sendToScript); + editRoot.push(Qt.resolvedUrl("../../" + path), itemProperties, + StackView.Immediate); + editRoot.currentItem.sendToScript.connect(editRoot.sendToScript); } function popSource() { - editStack.pop(); - } - - function fromScript(message) { - console.error("from script", JSON.stringify(message)) - switch (message.method) { - case 'selectTab': - selectTab(message.params.id); - break; - default: - var currentItem = editStack.currentItem; - if (currentItem && currentItem.fromScript) { - currentItem.fromScript(message); - } else { - console.warn('Unrecognized message:', JSON.stringify(message)); - } - } - } - - // Changes the current tab based on tab index or title as input - function selectTab(id) { - console.error("selecting tab", id) - if (typeof id === 'number') { - if (id >= 0 && id <= 4) { - editTabView.currentIndex = id; - } else { - console.warn('Attempt to switch to invalid tab:', id); - } - } else if (typeof id === 'string'){ - switch (id.toLowerCase()) { - case 'create': - editTabView.currentIndex = 0; - break; - case 'list': - editTabView.currentIndex = 1; - break; - case 'properties': - editTabView.currentIndex = 2; - break; - case 'grid': - editTabView.currentIndex = 3; - break; - case 'particle': - editTabView.currentIndex = 4; - break; - default: - console.warn('Attempt to switch to invalid tab:', id); - } - } else { - console.warn('Attempt to switch tabs with invalid input:', JSON.stringify(id)); - } - } - spacing: 0 - - HifiConstants { id: hifi } - - TabBar { - id: editTabView - height: 60 - width: parent.width - contentWidth: parent.width - currentIndex: 0 - padding: 0 - spacing: 0 - - onCurrentIndexChanged: { - if (currentIndex === 0) { - editStack.replace(null, mainTab, {}, StackView.Immediate) - } else { - editStack.replace(null, webViewTab, - {url: Paths.defaultScripts + webTabsLinks[currentIndex]}, - StackView.Immediate) - } - } - - EditTabButton { - text: "CREATE" - } - - EditTabButton { - text: "LIST" - } - - EditTabButton { - text: "PROPERTIES" - } - - EditTabButton { - text: "GRID" - } - - EditTabButton { - text: "P" - } - } - - StackView { - id: editStack - - Layout.fillHeight: true - Layout.fillWidth: true - initialItem: mainTab//Qt.resolvedUrl('EditTabView.qml') - } - - Component { - id: mainTab - - - Rectangle { //1st tab - color: "#404040" - - Text { - color: "#ffffff" - text: "Choose an Entity Type to Create:" - font.pixelSize: 14 - font.bold: true - anchors.top: parent.top - anchors.topMargin: 28 - anchors.left: parent.left - anchors.leftMargin: 28 - } - - Flow { - id: createEntitiesFlow - spacing: 35 - anchors.right: parent.right - anchors.rightMargin: 55 - anchors.left: parent.left - anchors.leftMargin: 55 - anchors.top: parent.top - anchors.topMargin: 70 - - - NewEntityButton { - icon: "icons/create-icons/94-model-01.svg" - text: "MODEL" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newModelButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/21-cube-01.svg" - text: "CUBE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newCubeButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/22-sphere-01.svg" - text: "SPHERE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newSphereButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/24-light-01.svg" - text: "LIGHT" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newLightButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/20-text-01.svg" - text: "TEXT" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newTextButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/25-web-1-01.svg" - text: "WEB" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newWebButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/23-zone-01.svg" - text: "ZONE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newZoneButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/90-particles-01.svg" - text: "PARTICLE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newParticleButton" } - }); - editTabView.currentIndex = 4 - } - } - } - - HifiControls.Button { - id: assetServerButton - text: "Open This Domain's Asset Server" - color: hifi.buttons.black - colorScheme: hifi.colorSchemes.dark - anchors.right: parent.right - anchors.rightMargin: 55 - anchors.left: parent.left - anchors.leftMargin: 55 - anchors.top: createEntitiesFlow.bottom - anchors.topMargin: 35 - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "openAssetBrowserButton" } - }); - } - } - - HifiControls.Button { - text: "Import Entities (.json)" - color: hifi.buttons.black - colorScheme: hifi.colorSchemes.dark - anchors.right: parent.right - anchors.rightMargin: 55 - anchors.left: parent.left - anchors.leftMargin: 55 - anchors.top: assetServerButton.bottom - anchors.topMargin: 20 - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "importEntitiesButton" } - }); - } - } - } - } - - Component { - id: webViewTab - WebView {} + editRoot.pop(StackView.Immediate); } } diff --git a/interface/resources/qml/hifi/tablet/EditTabButton.qml b/interface/resources/qml/hifi/tablet/EditTabButton.qml index 666ea16927..232c2ca792 100644 --- a/interface/resources/qml/hifi/tablet/EditTabButton.qml +++ b/interface/resources/qml/hifi/tablet/EditTabButton.qml @@ -1,6 +1,6 @@ // -// AudioTabButton.qml -// qml/hifi/audio +// EditTabButton.qml +// qml/hifi/tablet // // Created by Vlad Stelmahovsky on 8/16/2017 // Copyright 2017 High Fidelity, Inc. @@ -16,6 +16,9 @@ import "../../styles-uit" TabButton { id: control + property alias title: control.text + property alias active: control.checkable + height: 40 font.pixelSize: height / 2 padding: 0 spacing: 0 @@ -26,7 +29,7 @@ TabButton { text: control.text font.pixelSize: 14 font.bold: true - color: control.checked ? "white" : "white" + color: "white" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter property string glyphtext: "" diff --git a/interface/resources/qml/hifi/tablet/EditTabView.qml b/interface/resources/qml/hifi/tablet/EditTabView.qml index e419b04848..9a7958f95c 100644 --- a/interface/resources/qml/hifi/tablet/EditTabView.qml +++ b/interface/resources/qml/hifi/tablet/EditTabView.qml @@ -1,316 +1,286 @@ -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls 2.2 // Need both for short-term fix -import QtWebEngine 1.1 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import QtWebChannel 1.0 -import QtQuick.Controls.Styles 1.4 import "../../controls" import "../toolbars" import QtGraphicalEffects 1.0 import "../../controls-uit" as HifiControls import "../../styles-uit" - - -TabView { +TabBar { id: editTabView // anchors.fill: parent - height: 60 + width: parent.width + contentWidth: parent.width + padding: 0 + spacing: 0 - Tab { + readonly property HifiConstants hifi: HifiConstants {} + + EditTabButton { title: "CREATE" active: true enabled: true property string originalUrl: "" - Rectangle { - color: "#404040" - id: container + property Component visualItem: Component { - Flickable { - height: parent.height - width: parent.width + Rectangle { + color: "#404040" + id: container - contentHeight: createEntitiesFlow.height + importButton.height + assetServerButton.height + - header.anchors.topMargin + createEntitiesFlow.anchors.topMargin + - assetServerButton.anchors.topMargin + importButton.anchors.topMargin - contentWidth: width + Flickable { + height: parent.height + width: parent.width + clip: true - ScrollBar.vertical : ScrollBar { - visible: parent.contentHeight > parent.height - width: 20 - background: Rectangle { - color: hifi.colors.tableScrollBackgroundDark - } - } + contentHeight: createEntitiesFlow.height + importButton.height + assetServerButton.height + + header.anchors.topMargin + createEntitiesFlow.anchors.topMargin + + assetServerButton.anchors.topMargin + importButton.anchors.topMargin + + header.paintedHeight - Text { - id: header - color: "#ffffff" - text: "Choose an Entity Type to Create:" - font.pixelSize: 14 - font.bold: true - anchors.top: parent.top - anchors.topMargin: 28 - anchors.left: parent.left - anchors.leftMargin: 28 - } + contentWidth: width - Flow { - id: createEntitiesFlow - spacing: 35 - anchors.right: parent.right - anchors.rightMargin: 55 - anchors.left: parent.left - anchors.leftMargin: 55 - anchors.top: parent.top - anchors.topMargin: 70 + ScrollBar.vertical : ScrollBar { + visible: parent.contentHeight > parent.height + width: 20 + background: Rectangle { + color: hifi.colors.tableScrollBackgroundDark + } + } + + Text { + id: header + color: "#ffffff" + text: "Choose an Entity Type to Create:" + font.pixelSize: 14 + font.bold: true + anchors.top: parent.top + anchors.topMargin: 28 + anchors.left: parent.left + anchors.leftMargin: 28 + } + + Flow { + id: createEntitiesFlow + spacing: 35 + anchors.right: parent.right + anchors.rightMargin: 55 + anchors.left: parent.left + anchors.leftMargin: 55 + anchors.top: parent.top + anchors.topMargin: 70 - NewEntityButton { - icon: "icons/create-icons/94-model-01.svg" - text: "MODEL" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newModelButton" } - }); - editTabView.currentIndex = 2 + NewEntityButton { + icon: "icons/create-icons/94-model-01.svg" + text: "MODEL" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newModelButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/21-cube-01.svg" + text: "CUBE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newCubeButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/22-sphere-01.svg" + text: "SPHERE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newSphereButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/24-light-01.svg" + text: "LIGHT" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newLightButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/20-text-01.svg" + text: "TEXT" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newTextButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/image.svg" + text: "IMAGE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newImageButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/25-web-1-01.svg" + text: "WEB" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newWebButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/23-zone-01.svg" + text: "ZONE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newZoneButton" } + }); + editTabView.currentIndex = 2 + } + } + + NewEntityButton { + icon: "icons/create-icons/90-particles-01.svg" + text: "PARTICLE" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newParticleButton" } + }); + editTabView.currentIndex = 4 + } + } + + NewEntityButton { + icon: "icons/create-icons/126-material-01.svg" + text: "MATERIAL" + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "newMaterialButton" } + }); + editTabView.currentIndex = 2 + } + } + } + + HifiControls.Button { + id: assetServerButton + text: "Open This Domain's Asset Server" + color: hifi.buttons.black + colorScheme: hifi.colorSchemes.dark + anchors.right: parent.right + anchors.rightMargin: 55 + anchors.left: parent.left + anchors.leftMargin: 55 + anchors.top: createEntitiesFlow.bottom + anchors.topMargin: 35 + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "openAssetBrowserButton" } + }); + } + } + + HifiControls.Button { + id: importButton + text: "Import Entities (.json)" + color: hifi.buttons.black + colorScheme: hifi.colorSchemes.dark + anchors.right: parent.right + anchors.rightMargin: 55 + anchors.left: parent.left + anchors.leftMargin: 55 + anchors.top: assetServerButton.bottom + anchors.topMargin: 20 + onClicked: { + editRoot.sendToScript({ + method: "newEntityButtonClicked", params: { buttonName: "importEntitiesButton" } + }); + } } } - - NewEntityButton { - icon: "icons/create-icons/21-cube-01.svg" - text: "CUBE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newCubeButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/22-sphere-01.svg" - text: "SPHERE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newSphereButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/24-light-01.svg" - text: "LIGHT" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newLightButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/20-text-01.svg" - text: "TEXT" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newTextButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/image.svg" - text: "IMAGE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newImageButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/25-web-1-01.svg" - text: "WEB" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newWebButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/23-zone-01.svg" - text: "ZONE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newZoneButton" } - }); - editTabView.currentIndex = 2 - } - } - - NewEntityButton { - icon: "icons/create-icons/90-particles-01.svg" - text: "PARTICLE" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newParticleButton" } - }); - editTabView.currentIndex = 4 - } - } - - NewEntityButton { - icon: "icons/create-icons/126-material-01.svg" - text: "MATERIAL" - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "newMaterialButton" } - }); - editTabView.currentIndex = 2 - } - } - } - - HifiControls.Button { - id: assetServerButton - text: "Open This Domain's Asset Server" - color: hifi.buttons.black - colorScheme: hifi.colorSchemes.dark - anchors.right: parent.right - anchors.rightMargin: 55 - anchors.left: parent.left - anchors.leftMargin: 55 - anchors.top: createEntitiesFlow.bottom - anchors.topMargin: 35 - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "openAssetBrowserButton" } - }); - } - } - - HifiControls.Button { - id: importButton - text: "Import Entities (.json)" - color: hifi.buttons.black - colorScheme: hifi.colorSchemes.dark - anchors.right: parent.right - anchors.rightMargin: 55 - anchors.left: parent.left - anchors.leftMargin: 55 - anchors.top: assetServerButton.bottom - anchors.topMargin: 20 - onClicked: { - editRoot.sendToScript({ - method: "newEntityButtonClicked", params: { buttonName: "importEntitiesButton" } - }); - } - } + } // Flickable } - } // Flickable } - Tab { + EditTabButton { title: "LIST" active: true enabled: true property string originalUrl: "" - WebView { - id: entityListToolWebView - url: Paths.defaultScripts + "/system/html/entityList.html" - anchors.fill: parent - enabled: true + property Component visualItem: Component { + WebView { + id: entityListToolWebView + url: Paths.defaultScripts + "/system/html/entityList.html" + enabled: true + } } } - Tab { + EditTabButton { title: "PROPERTIES" active: true enabled: true property string originalUrl: "" - WebView { - id: entityPropertiesWebView - url: Paths.defaultScripts + "/system/html/entityProperties.html" - anchors.fill: parent - enabled: true + property Component visualItem: Component { + WebView { + id: entityPropertiesWebView + url: Paths.defaultScripts + "/system/html/entityProperties.html" + enabled: true + } } } - Tab { + EditTabButton { title: "GRID" active: true enabled: true property string originalUrl: "" - WebView { - id: gridControlsWebView - url: Paths.defaultScripts + "/system/html/gridControls.html" - anchors.fill: parent - enabled: true + property Component visualItem: Component { + WebView { + id: gridControlsWebView + url: Paths.defaultScripts + "/system/html/gridControls.html" + enabled: true + } } } - Tab { + EditTabButton { title: "P" active: true enabled: true property string originalUrl: "" - WebView { - id: particleExplorerWebView - url: Paths.defaultScripts + "/system/particle_explorer/particleExplorer.html" - anchors.fill: parent - enabled: true - } - } - - - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle { - color: styleData.selected ? "#404040" :"black" - implicitWidth: text.width + 42 - implicitHeight: 40 - Text { - id: text - anchors.centerIn: parent - text: styleData.title - font.pixelSize: 16 - font.bold: true - color: styleData.selected ? "white" : "white" - property string glyphtext: "" - HiFiGlyphs { - anchors.centerIn: parent - size: 30 - color: "#ffffff" - text: text.glyphtext - } - Component.onCompleted: if (styleData.title == "P") { - text.text = " "; - text.glyphtext = "\ue004"; - } + property Component visualItem: Component { + WebView { + id: particleExplorerWebView + url: Paths.defaultScripts + "/system/particle_explorer/particleExplorer.html" + enabled: true } } - tabBar: Rectangle { - color: "black" - anchors.right: parent.right - anchors.rightMargin: 0 - anchors.left: parent.left - anchors.leftMargin: 0 - anchors.bottom: parent.bottom - anchors.bottomMargin: 0 - anchors.top: parent.top - anchors.topMargin: 0 - } } function fromScript(message) { diff --git a/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml b/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml index 25b5be05f2..3114c79bfe 100644 --- a/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml +++ b/interface/resources/qml/hifi/tablet/TabletGraphicsPreferences.qml @@ -8,8 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 2.2 import "tabletWindows" import "../../dialogs" From f51025061ca1de30fa41b6ce9a1f2881ea799867 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 1 Mar 2018 11:03:56 +0100 Subject: [PATCH 033/109] Make Edit view more consistant with original one #2 --- interface/resources/qml/hifi/tablet/Edit.qml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/Edit.qml b/interface/resources/qml/hifi/tablet/Edit.qml index 28d6094194..d5edf4c5af 100644 --- a/interface/resources/qml/hifi/tablet/Edit.qml +++ b/interface/resources/qml/hifi/tablet/Edit.qml @@ -9,7 +9,9 @@ import "../toolbars" StackView { id: editRoot objectName: "stack" - //anchors.fill: parent + + signal sendToScript(var message); + topPadding: 40 property var itemProperties: {"y": editRoot.topPadding, @@ -32,8 +34,6 @@ StackView { } } - signal sendToScript(var message); - function pushSource(path) { editRoot.push(Qt.resolvedUrl("../../" + path), itemProperties, StackView.Immediate); @@ -43,5 +43,12 @@ StackView { function popSource() { editRoot.pop(StackView.Immediate); } + + // Passes script messages to the item on the top of the stack + function fromScript(message) { + var currentItem = editRoot.currentItem; + if (currentItem && currentItem.fromScript) + currentItem.fromScript(message); + } } From 02612e04650e19325e13de7074c3933b8539a1da Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 1 Mar 2018 11:18:18 +0100 Subject: [PATCH 034/109] cleanup and fits text to buttons --- interface/resources/qml/hifi/tablet/Edit.qml | 5 ----- interface/resources/qml/hifi/tablet/EditTabButton.qml | 5 +++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/Edit.qml b/interface/resources/qml/hifi/tablet/Edit.qml index d5edf4c5af..ef38cdeb51 100644 --- a/interface/resources/qml/hifi/tablet/Edit.qml +++ b/interface/resources/qml/hifi/tablet/Edit.qml @@ -1,10 +1,5 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import "../../styles-uit" -import "../../controls-uit" as HifiControls -import "../../controls" -import "../toolbars" StackView { id: editRoot diff --git a/interface/resources/qml/hifi/tablet/EditTabButton.qml b/interface/resources/qml/hifi/tablet/EditTabButton.qml index 232c2ca792..13894f4d15 100644 --- a/interface/resources/qml/hifi/tablet/EditTabButton.qml +++ b/interface/resources/qml/hifi/tablet/EditTabButton.qml @@ -19,7 +19,6 @@ TabButton { property alias title: control.text property alias active: control.checkable height: 40 - font.pixelSize: height / 2 padding: 0 spacing: 0 HifiConstants { id: hifi; } @@ -32,6 +31,7 @@ TabButton { color: "white" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter + fontSizeMode: Text.HorizontalFit property string glyphtext: "" HiFiGlyphs { anchors.centerIn: parent @@ -49,7 +49,8 @@ TabButton { background: Rectangle { color: control.checked ? "#404040" :"black" - implicitWidth: control.contentItem.width + 42 + implicitWidth: control.contentItem.width + 42 > text.paintedWidth ? control.contentItem.width + 42 : + text.paintedWidth + 10 implicitHeight: 40 } } From 94e070eae25089e2a59498ba01414d99855607f7 Mon Sep 17 00:00:00 2001 From: vladest Date: Sun, 4 Mar 2018 15:14:49 +0100 Subject: [PATCH 035/109] Try to fix incorrectly visible scrollbars on Mac --- interface/resources/qml/windows/ScrollingWindow.qml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 94cab7fd29..5f0780a748 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -44,7 +44,7 @@ Window { // type should only consist of logic sized areas, with nothing drawn (although the // default value for the frame property does include visual decorations) property var pane: Item { - property bool isScrolling: scrollView.height < scrollView.contentItem.height + property bool isScrolling: scrollView.contentHeight > scrollView.availableHeight property int contentWidth: scrollView.width - (isScrolling ? 10 : 0) property int scrollHeight: scrollView.height @@ -86,14 +86,11 @@ Window { anchors.bottomMargin: footerPane.height ScrollBar.vertical: ScrollBar { - id: control policy: ScrollBar.AsNeeded - parent: scrollView x: scrollView.width - width y: scrollView.topPadding height: scrollView.availableHeight - active: scrollView.ScrollBar.vertical.active - visible: control.size < 1.0 + visible: scrollView.contentHeight > scrollView.availableHeight background: Item { implicitWidth: 10 Rectangle { From 698a224bb0e17f54eab0f2042d90dc60d84dd165 Mon Sep 17 00:00:00 2001 From: vladest Date: Tue, 6 Mar 2018 16:13:46 +0100 Subject: [PATCH 036/109] Next attempt to fix ghosted scroll bars --- .../resources/qml/windows/ScrollingWindow.qml | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 5f0780a748..2346522172 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -38,24 +38,26 @@ Window { property bool keyboardRaised: false property bool punctuationMode: false + readonly property real verticalScrollWidth: 10 + readonly property real verticalScrollShaft: 8 + // Scrollable window content. // FIXME this should not define any visual content in this type. The base window // type should only consist of logic sized areas, with nothing drawn (although the // default value for the frame property does include visual decorations) property var pane: Item { - property bool isScrolling: scrollView.contentHeight > scrollView.availableHeight + property bool isScrolling: Qt.binding(function() { return scrollView.contentHeight > scrollView.availableHeight; }); - property int contentWidth: scrollView.width - (isScrolling ? 10 : 0) - property int scrollHeight: scrollView.height + property int contentWidth: scrollView.availableWidth + property int scrollHeight: scrollView.availableHeight anchors.fill: parent - anchors.rightMargin: isScrolling ? 11 : 0 Rectangle { id: contentBackground anchors.fill: parent - anchors.rightMargin: parent.isScrolling ? 11 : 0 + //anchors.rightMargin: parent.isScrolling ? verticalScrollWidth + 1 : 0 color: hifi.colors.baseGray visible: !window.hideBackground && modality != Qt.ApplicationModal } @@ -77,22 +79,23 @@ Window { ScrollView { id: scrollView - contentItem: content + contentChildren: content ScrollBar.horizontal.policy: ScrollBar.AlwaysOff clip: true + anchors.rightMargin: parent.isScrolling ? verticalScrollWidth : 0 anchors.fill: parent - anchors.rightMargin: parent.isScrolling ? 1 : 0 anchors.bottomMargin: footerPane.height ScrollBar.vertical: ScrollBar { - policy: ScrollBar.AsNeeded - x: scrollView.width - width - y: scrollView.topPadding - height: scrollView.availableHeight - visible: scrollView.contentHeight > scrollView.availableHeight + policy: scrollView.contentHeight > scrollView.availableHeight ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff + parent: scrollView.parent + anchors.top: scrollView.top + anchors.right: scrollView.right + anchors.bottom: scrollView.bottom + anchors.rightMargin: -verticalScrollWidth //compensate scrollview's right margin background: Item { - implicitWidth: 10 + implicitWidth: verticalScrollWidth Rectangle { color: hifi.colors.darkGray30 radius: 4 @@ -104,9 +107,9 @@ Window { } } contentItem: Item { - implicitWidth: 8 + implicitWidth: verticalScrollShaft Rectangle { - radius: 4 + radius: verticalScrollShaft/2 color: hifi.colors.white30 anchors { fill: parent From 405951e4114140b815cb7553b1abe328f6362ff0 Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 10 Mar 2018 14:45:20 +0100 Subject: [PATCH 037/109] Fix merge conflict --- interface/resources/qml/controls-uit/Button.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/resources/qml/controls-uit/Button.qml b/interface/resources/qml/controls-uit/Button.qml index 4ac2f8dd12..5938414897 100644 --- a/interface/resources/qml/controls-uit/Button.qml +++ b/interface/resources/qml/controls-uit/Button.qml @@ -23,8 +23,6 @@ Original.Button { property Action action: null - width: 120 - width: hifi.dimensions.buttonWidth height: hifi.dimensions.controlLineHeight From 387be7415f8eb674ddf2a470a754465386b18c35 Mon Sep 17 00:00:00 2001 From: vladest Date: Wed, 14 Mar 2018 19:00:19 +0100 Subject: [PATCH 038/109] WIP: do not push --- .../qml/dialogs/PreferencesDialog.qml | 10 +++++----- .../resources/qml/windows/ScrollingWindow.qml | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/interface/resources/qml/dialogs/PreferencesDialog.qml b/interface/resources/qml/dialogs/PreferencesDialog.qml index 601f350ed5..0a97ab9241 100644 --- a/interface/resources/qml/dialogs/PreferencesDialog.qml +++ b/interface/resources/qml/dialogs/PreferencesDialog.qml @@ -26,7 +26,7 @@ ScrollingWindow { property var showCategories: [] minSize: Qt.vector2d(400, 500) - HifiConstants { id: hifi } + //HifiConstants { id: hifi } function saveAll() { for (var i = 0; i < sections.length; ++i) { @@ -96,19 +96,19 @@ ScrollingWindow { anchors { top: parent.top right: parent.right - rightMargin: hifi.dimensions.contentMargin.x + rightMargin: 10//hifi.dimensions.contentMargin.x } - spacing: hifi.dimensions.contentSpacing.x + spacing: 1//hifi.dimensions.contentSpacing.x HifiControls.Button { text: "Save changes" - color: hifi.buttons.blue + color: 1//hifi.buttons.blue onClicked: root.saveAll() } HifiControls.Button { text: "Cancel" - color: hifi.buttons.white + color: 2//hifi.buttons.white onClicked: root.restoreAll() } } diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 2346522172..8a439a0d1d 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -47,10 +47,10 @@ Window { // type should only consist of logic sized areas, with nothing drawn (although the // default value for the frame property does include visual decorations) property var pane: Item { - property bool isScrolling: Qt.binding(function() { return scrollView.contentHeight > scrollView.availableHeight; }); + property bool isScrolling: Qt.binding(function() { return scrollView.contentHeight > scrollView.height; }); - property int contentWidth: scrollView.availableWidth - property int scrollHeight: scrollView.availableHeight + property int contentWidth: scrollView.width + property int scrollHeight: scrollView.height anchors.fill: parent @@ -77,10 +77,13 @@ Window { cached: true } - ScrollView { + Flickable { id: scrollView - contentChildren: content - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + children: [ content ] + //contentItem: content + //onContentItemChanged: console.log("content item", contentItem) + + //ScrollBar.horizontal.policy: ScrollBar.AlwaysOff clip: true anchors.rightMargin: parent.isScrolling ? verticalScrollWidth : 0 @@ -88,8 +91,8 @@ Window { anchors.bottomMargin: footerPane.height ScrollBar.vertical: ScrollBar { - policy: scrollView.contentHeight > scrollView.availableHeight ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff - parent: scrollView.parent + policy: scrollView.contentHeight > scrollView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff + parent: scrollView anchors.top: scrollView.top anchors.right: scrollView.right anchors.bottom: scrollView.bottom From f356de5fdfc519447a932a623aa1d7b2317af7fe Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Fri, 16 Mar 2018 11:51:03 -0700 Subject: [PATCH 039/109] Updating repo script to match marketplace script --- scripts/tutorials/entity_scripts/sit.js | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/scripts/tutorials/entity_scripts/sit.js b/scripts/tutorials/entity_scripts/sit.js index 70456ea493..9de65d7037 100644 --- a/scripts/tutorials/entity_scripts/sit.js +++ b/scripts/tutorials/entity_scripts/sit.js @@ -12,9 +12,9 @@ Script.include("/~/system/libraries/utils.js"); if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position){ - position = position || 0; - return this.substr(position, searchString.length) === searchString; - }; + position = position || 0; + return this.substr(position, searchString.length) === searchString; + }; } var SETTING_KEY = "com.highfidelity.avatar.isSitting"; @@ -122,20 +122,10 @@ this.rolesToOverride = function() { return MyAvatar.getAnimationRoles().filter(function(role) { - return !(role.startsWith("right") || role.startsWith("left")); + return !(role.startsWith("right") || role.startsWith("left")); }); } - // Handler for user changing the avatar model while sitting. There's currently an issue with changing avatar models while override role animations are applied, - // so to avoid that problem, re-apply the role overrides once the model has finished changing. - this.modelURLChangeFinished = function () { - print("Sitter's model has FINISHED changing. Reapply anim role overrides."); - var roles = this.rolesToOverride(); - for (i in roles) { - MyAvatar.overrideRoleAnimation(roles[i], ANIMATION_URL, ANIMATION_FPS, true, ANIMATION_FIRST_FRAME, ANIMATION_LAST_FRAME); - } - } - this.sitDown = function() { if (this.checkSeatForAvatar()) { print("Someone is already sitting in that chair."); @@ -174,14 +164,12 @@ return { headType: 0 }; }, ["headType"]); Script.update.connect(this, this.update); - MyAvatar.onLoadComplete.connect(this, this.modelURLChangeFinished); } this.standUp = function() { print("Standing up (" + this.entityID + ")"); MyAvatar.removeAnimationStateHandler(this.animStateHandlerID); Script.update.disconnect(this, this.update); - MyAvatar.onLoadComplete.disconnect(this, this.modelURLChangeFinished); if (MyAvatar.sessionUUID === this.getSeatUser()) { this.setSeatUser(null); @@ -343,7 +331,7 @@ } this.cleanupOverlay(); } - + this.clickDownOnEntity = function (id, event) { if (isInEditMode()) { return; @@ -352,4 +340,4 @@ this.sitDown(); } } -}); +}); \ No newline at end of file From 9d9b08803c7076b4c4310559e5b35b74304e3e6d Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 19 Mar 2018 01:17:46 -0400 Subject: [PATCH 040/109] Corrected getAnimatationRoles to getAnimationRoles --- interface/src/avatar/MyAvatar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 5ca010d128..7a5bfc5db4 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -299,7 +299,7 @@ public: * (such as look at vectors, hand sensors etc.). Each animation specified in the avatar-animation.json file is known as an animation role. * Animation roles map to easily understandable actions that the avatar can perform, such as "idleStand", "idleTalk", or "walkFwd." * getAnimationRoles() is used get the list of animation roles defined in the avatar-animation.json. - * @function MyAvatar.getAnimatationRoles + * @function MyAvatar.getAnimationRoles * @example This example prints the list of animation roles defined in the avatar's avatar-animation.json file to the debug log. * var roles = MyAvatar.getAnimationRoles(); * print("Animation Roles:"); From 35551f045c120bb2664be13dc85c0c4da1bf0bee Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Wed, 21 Mar 2018 15:35:10 -0700 Subject: [PATCH 041/109] Updating with jshint edits --- scripts/tutorials/entity_scripts/sit.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/tutorials/entity_scripts/sit.js b/scripts/tutorials/entity_scripts/sit.js index 9de65d7037..9c994ed2ea 100644 --- a/scripts/tutorials/entity_scripts/sit.js +++ b/scripts/tutorials/entity_scripts/sit.js @@ -145,11 +145,11 @@ MyAvatar.characterControllerEnabled = false; MyAvatar.hmdLeanRecenterEnabled = false; var roles = this.rolesToOverride(); - for (i in roles) { + for (var i = 0; i < roles.length; i++) { MyAvatar.overrideRoleAnimation(roles[i], ANIMATION_URL, ANIMATION_FPS, true, ANIMATION_FIRST_FRAME, ANIMATION_LAST_FRAME); } - for (var i in OVERRIDEN_DRIVE_KEYS) { + for (i = 0; i < OVERRIDEN_DRIVE_KEYS.length; i++) { MyAvatar.disableDriveKey(OVERRIDEN_DRIVE_KEYS[i]); } @@ -178,12 +178,12 @@ if (Settings.getValue(SETTING_KEY) === this.entityID) { Settings.setValue(SETTING_KEY, ""); - for (var i in OVERRIDEN_DRIVE_KEYS) { + for (var i = 0; i < OVERRIDEN_DRIVE_KEYS.length; i++) { MyAvatar.enableDriveKey(OVERRIDEN_DRIVE_KEYS[i]); } var roles = this.rolesToOverride(); - for (i in roles) { + for (i = 0; i < roles.length; i++) { MyAvatar.restoreRoleAnimation(roles[i]); } MyAvatar.characterControllerEnabled = true; @@ -260,7 +260,7 @@ // Check if a drive key is pressed var hasActiveDriveKey = false; for (var i in OVERRIDEN_DRIVE_KEYS) { - if (MyAvatar.getRawDriveKey(OVERRIDEN_DRIVE_KEYS[i]) != 0.0) { + if (MyAvatar.getRawDriveKey(OVERRIDEN_DRIVE_KEYS[i]) !== 0.0) { hasActiveDriveKey = true; break; } From e0593b779934b16d91aaf9402ffcee886d2344aa Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 24 Mar 2018 15:32:46 +0100 Subject: [PATCH 042/109] Use Flickable instead of ScrollView --- interface/resources/qml/windows/ScrollingWindow.qml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 8a439a0d1d..61e22c0400 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -41,7 +41,6 @@ Window { readonly property real verticalScrollWidth: 10 readonly property real verticalScrollShaft: 8 - // Scrollable window content. // FIXME this should not define any visual content in this type. The base window // type should only consist of logic sized areas, with nothing drawn (although the @@ -79,11 +78,10 @@ Window { Flickable { id: scrollView - children: [ content ] - //contentItem: content - //onContentItemChanged: console.log("content item", contentItem) + contentItem.children: [ content ] + contentHeight: content.height + boundsBehavior: Flickable.StopAtBounds - //ScrollBar.horizontal.policy: ScrollBar.AlwaysOff clip: true anchors.rightMargin: parent.isScrolling ? verticalScrollWidth : 0 @@ -92,7 +90,7 @@ Window { ScrollBar.vertical: ScrollBar { policy: scrollView.contentHeight > scrollView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff - parent: scrollView + parent: scrollView.parent anchors.top: scrollView.top anchors.right: scrollView.right anchors.bottom: scrollView.bottom From 096b56395ebd10fe7601ede3326c9188b91eae7a Mon Sep 17 00:00:00 2001 From: vladest Date: Tue, 27 Mar 2018 18:22:56 +0200 Subject: [PATCH 043/109] Fix crash on startup --- interface/resources/qml/controls-uit/Action.qml | 8 -------- interface/resources/qml/controls-uit/Button.qml | 13 +------------ .../resources/qml/controls-uit/GlyphButton.qml | 10 ---------- interface/resources/qml/controls-uit/Table.qml | 2 +- interface/resources/qml/desktop/Desktop.qml | 5 +++-- .../resources/qml/dialogs/CustomQueryDialog.qml | 5 +++-- interface/resources/qml/dialogs/FileDialog.qml | 1 + interface/resources/qml/dialogs/QueryDialog.qml | 7 ++++--- .../qml/dialogs/TabletCustomQueryDialog.qml | 5 +++-- .../resources/qml/dialogs/TabletFileDialog.qml | 1 + .../resources/qml/dialogs/TabletQueryDialog.qml | 5 +++-- .../qml/dialogs/assetDialog/AssetDialogContent.qml | 5 +++-- interface/resources/qml/hifi/Desktop.qml | 2 ++ .../qml/hifi/dialogs/AvatarAttachmentsDialog.qml | 8 ++++---- .../qml/hifi/dialogs/content/AttachmentsContent.qml | 6 +++--- .../hifi/dialogs/content/ModelBrowserContent.qml | 11 ++++++----- 16 files changed, 38 insertions(+), 56 deletions(-) delete mode 100644 interface/resources/qml/controls-uit/Action.qml diff --git a/interface/resources/qml/controls-uit/Action.qml b/interface/resources/qml/controls-uit/Action.qml deleted file mode 100644 index 5dbfa3914b..0000000000 --- a/interface/resources/qml/controls-uit/Action.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.7 - -Shortcut { - id: root - property string text - property alias shortcut: root.sequence - signal triggered() -} diff --git a/interface/resources/qml/controls-uit/Button.qml b/interface/resources/qml/controls-uit/Button.qml index 5938414897..0119d76ac2 100644 --- a/interface/resources/qml/controls-uit/Button.qml +++ b/interface/resources/qml/controls-uit/Button.qml @@ -9,7 +9,7 @@ // import QtQuick 2.7 -import QtQuick.Controls 2.2 as Original +import QtQuick.Controls 2.3 as Original import TabletScriptingInterface 1.0 import "../styles-uit" @@ -21,8 +21,6 @@ Original.Button { property int colorScheme: hifi.colorSchemes.light property string buttonGlyph: ""; - property Action action: null - width: hifi.dimensions.buttonWidth height: hifi.dimensions.controlLineHeight @@ -40,17 +38,8 @@ Original.Button { } } - onActionChanged: { - if (action !== null && action.text !== "") { - control.text = action.text - } - } - onClicked: { Tablet.playSound(TabletEnums.ButtonClick); - if (action !== null) { - action.triggered() - } } background: Rectangle { diff --git a/interface/resources/qml/controls-uit/GlyphButton.qml b/interface/resources/qml/controls-uit/GlyphButton.qml index 66e29f8508..9129486720 100644 --- a/interface/resources/qml/controls-uit/GlyphButton.qml +++ b/interface/resources/qml/controls-uit/GlyphButton.qml @@ -24,18 +24,11 @@ Original.Button { width: 120 height: 28 - property Action action: null - onHoveredChanged: { if (hovered) { Tablet.playSound(TabletEnums.ButtonHover); } } - onActionChanged: { - if (action !== null && action.text !== "") { - control.text = action.text - } - } onFocusChanged: { if (focus) { @@ -45,9 +38,6 @@ Original.Button { onClicked: { Tablet.playSound(TabletEnums.ButtonClick); - if (action !== null) { - action.triggered() - } } background: Rectangle { diff --git a/interface/resources/qml/controls-uit/Table.qml b/interface/resources/qml/controls-uit/Table.qml index 3c1d0fcd3c..ce4e1c376a 100644 --- a/interface/resources/qml/controls-uit/Table.qml +++ b/interface/resources/qml/controls-uit/Table.qml @@ -11,7 +11,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 -import QtQuick.Controls 2.2 as QQC2 +import QtQuick.Controls 2.3 as QQC2 import "../styles-uit" diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index e7c68b2a47..aa1049aff5 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -8,8 +8,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 +import QtQuick 2.7 import QtQuick.Controls 1.4 +import QtQuick.Controls 2.3 as QQC2 import "../dialogs" import "../js/Utils.js" as Utils @@ -565,7 +566,7 @@ FocusScope { ColorAnimation on color { from: "#7fffff00"; to: "#7f0000ff"; duration: 1000; loops: 9999 } } - Action { + QQC2.Action { text: "Toggle Focus Debugger" shortcut: "Ctrl+Shift+F" enabled: DebugQML diff --git a/interface/resources/qml/dialogs/CustomQueryDialog.qml b/interface/resources/qml/dialogs/CustomQueryDialog.qml index 403cd526ce..283b320758 100644 --- a/interface/resources/qml/dialogs/CustomQueryDialog.qml +++ b/interface/resources/qml/dialogs/CustomQueryDialog.qml @@ -10,6 +10,7 @@ import QtQuick 2.7; import QtQuick.Dialogs 1.2 as OriginalDialogs; +import QtQuick.Controls 2.3 import "../controls-uit"; import "../styles-uit"; @@ -265,7 +266,7 @@ ModalWindow { Action { id: cancelAction; text: qsTr("Cancel"); - shortcut: Qt.Key_Escape; + shortcut: "Esc"; onTriggered: { root.result = null; root.canceled(); @@ -276,7 +277,7 @@ ModalWindow { Action { id: acceptAction; text: qsTr("Add"); - shortcut: Qt.Key_Return; + shortcut: "Return" onTriggered: { var result = {}; if (textInput) { diff --git a/interface/resources/qml/dialogs/FileDialog.qml b/interface/resources/qml/dialogs/FileDialog.qml index 02e33f8f35..154d66378b 100644 --- a/interface/resources/qml/dialogs/FileDialog.qml +++ b/interface/resources/qml/dialogs/FileDialog.qml @@ -13,6 +13,7 @@ import Qt.labs.folderlistmodel 2.1 import Qt.labs.settings 1.0 import QtQuick.Dialogs 1.2 as OriginalDialogs import QtQuick.Controls 1.4 as QQC1 +import QtQuick.Controls 2.3 import ".." import "../controls-uit" diff --git a/interface/resources/qml/dialogs/QueryDialog.qml b/interface/resources/qml/dialogs/QueryDialog.qml index d7a88796b2..fcc4b1c2b9 100644 --- a/interface/resources/qml/dialogs/QueryDialog.qml +++ b/interface/resources/qml/dialogs/QueryDialog.qml @@ -8,7 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.5 +import QtQuick 2.7 +import QtQuick.Controls 2.3 import "../controls-uit" import "../styles-uit" @@ -164,7 +165,7 @@ ModalWindow { Action { id: cancelAction text: qsTr("Cancel"); - sequence: Qt.Key_Escape + shortcut: "Esc" onTriggered: { root.canceled(); root.destroy(); @@ -174,7 +175,7 @@ ModalWindow { Action { id: acceptAction text: qsTr("OK"); - sequence: Qt.Key_Return + shortcut: "Return" onTriggered: { root.result = items ? comboBox.currentText : textResult.text root.selected(root.result); diff --git a/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml b/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml index 8652e37571..a0cfa3205b 100644 --- a/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml @@ -10,6 +10,7 @@ import QtQuick 2.7 import QtQuick.Dialogs 1.2 as OriginalDialogs +import QtQuick.Controls 2.3 import "../controls-uit" import "../styles-uit" @@ -293,7 +294,7 @@ TabletModalWindow { Action { id: cancelAction; text: qsTr("Cancel"); - shortcut: Qt.Key_Escape; + shortcut: "Esc"; onTriggered: { root.result = null; root.canceled(); @@ -304,7 +305,7 @@ TabletModalWindow { Action { id: acceptAction; text: qsTr("Add"); - shortcut: Qt.Key_Return; + shortcut: "Return"; onTriggered: { var result = {}; if (textInput) { diff --git a/interface/resources/qml/dialogs/TabletFileDialog.qml b/interface/resources/qml/dialogs/TabletFileDialog.qml index 9dc4f0211a..db15337913 100644 --- a/interface/resources/qml/dialogs/TabletFileDialog.qml +++ b/interface/resources/qml/dialogs/TabletFileDialog.qml @@ -13,6 +13,7 @@ import Qt.labs.folderlistmodel 2.1 import Qt.labs.settings 1.0 import QtQuick.Dialogs 1.2 as OriginalDialogs import QtQuick.Controls 1.4 as QQC1 +import QtQuick.Controls 2.3 import ".." import "../controls-uit" diff --git a/interface/resources/qml/dialogs/TabletQueryDialog.qml b/interface/resources/qml/dialogs/TabletQueryDialog.qml index 7b9a91e467..5746a3d67c 100644 --- a/interface/resources/qml/dialogs/TabletQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletQueryDialog.qml @@ -10,6 +10,7 @@ import QtQuick 2.7 import QtQuick.Dialogs 1.2 as OriginalDialogs +import QtQuick.Controls 2.3 import "../controls-uit" import "../styles-uit" @@ -143,7 +144,7 @@ TabletModalWindow { Action { id: cancelAction text: qsTr("Cancel") - shortcut: Qt.Key_Escape + shortcut: "Esc" onTriggered: { root.canceled(); root.destroy(); @@ -152,7 +153,7 @@ TabletModalWindow { Action { id: acceptAction text: qsTr("OK") - shortcut: Qt.Key_Return + shortcut: "Return" onTriggered: { root.result = items ? comboBox.currentText : textResult.text root.selected(root.result); diff --git a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml index cdf8e28312..d49e1e11be 100644 --- a/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml +++ b/interface/resources/qml/dialogs/assetDialog/AssetDialogContent.qml @@ -9,7 +9,8 @@ // import QtQuick 2.7 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.3 +import QtQuick.Controls 1.5 as QQC1 import "../../controls-uit" import "../../styles-uit" @@ -362,7 +363,7 @@ Item { } } - TableViewColumn { + QQC1.TableViewColumn { id: fileNameColumn role: "fileName" title: "Name" diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index feb0ecb2e0..24111ad935 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -2,6 +2,8 @@ import QtQuick 2.7 import QtWebEngine 1.5; import Qt.labs.settings 1.0 +import QtQuick.Controls 2.3 + import "../desktop" as OriginalDesktop import ".." import "." diff --git a/interface/resources/qml/hifi/dialogs/AvatarAttachmentsDialog.qml b/interface/resources/qml/hifi/dialogs/AvatarAttachmentsDialog.qml index 5de0864df5..b4357a0077 100644 --- a/interface/resources/qml/hifi/dialogs/AvatarAttachmentsDialog.qml +++ b/interface/resources/qml/hifi/dialogs/AvatarAttachmentsDialog.qml @@ -1,5 +1,5 @@ -import QtQuick 2.5 -import QtQuick.Controls 1.4 +import QtQuick 2.7 +import QtQuick.Controls 1.5 import QtQuick.XmlListModel 2.0 import QtQuick.Controls.Styles 1.4 @@ -104,7 +104,7 @@ ModalWindow { id: acceptAction text: qsTr("OK") enabled: root.result ? true : false - shortcut: Qt.Key_Return + shortcut: "Return" onTriggered: { root.selected(root.result); root.destroy(); @@ -114,7 +114,7 @@ ModalWindow { Action { id: cancelAction text: qsTr("Cancel") - shortcut: Qt.Key_Escape + shortcut: "Esc" onTriggered: { root.canceled(); root.destroy(); diff --git a/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml b/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml index 67a85bfe8d..fa71116574 100644 --- a/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml +++ b/interface/resources/qml/hifi/dialogs/content/AttachmentsContent.qml @@ -1,5 +1,5 @@ import QtQuick 2.7 -import QtQuick.Controls 2.2 +import QtQuick.Controls 2.3 import QtQuick.Dialogs 1.2 as OriginalDialogs import "../../../styles-uit" @@ -256,7 +256,7 @@ Item { } } - HifiControls.Action { + Action { id: cancelAction text: "Cancel" onTriggered: { @@ -265,7 +265,7 @@ Item { } } - HifiControls.Action { + Action { id: okAction text: "OK" onTriggered: { diff --git a/interface/resources/qml/hifi/dialogs/content/ModelBrowserContent.qml b/interface/resources/qml/hifi/dialogs/content/ModelBrowserContent.qml index c9fe9840b8..ce1abc6154 100644 --- a/interface/resources/qml/hifi/dialogs/content/ModelBrowserContent.qml +++ b/interface/resources/qml/hifi/dialogs/content/ModelBrowserContent.qml @@ -1,4 +1,5 @@ -import QtQuick 2.5 +import QtQuick 2.7 +import QtQuick.Controls 2.3 import "../../../controls-uit" as HifiControls @@ -39,21 +40,21 @@ Column { HifiControls.Button { action: cancelAction ; color: hifi.buttons.black; colorScheme: hifi.colorSchemes.dark } } - HifiControls.Action { + Action { id: acceptAction text: qsTr("OK") enabled: root.result ? true : false - shortcut: Qt.Key_Return + shortcut: "Return" onTriggered: { root.selected(root.result); root.destroy(); } } - HifiControls.Action { + Action { id: cancelAction text: qsTr("Cancel") - shortcut: Qt.Key_Escape + shortcut: "Esc" onTriggered: { root.canceled(); root.destroy(); From 70ce1b2bf7e5b310fe2875f5bc965116ee69dd46 Mon Sep 17 00:00:00 2001 From: vladest Date: Wed, 28 Mar 2018 21:48:44 +0200 Subject: [PATCH 044/109] Fix invalid scrolling detection --- interface/resources/qml/hifi/tablet/Edit.qml | 6 +++++- interface/resources/qml/windows/ScrollingWindow.qml | 7 +++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/Edit.qml b/interface/resources/qml/hifi/tablet/Edit.qml index ef38cdeb51..4acced86ce 100644 --- a/interface/resources/qml/hifi/tablet/Edit.qml +++ b/interface/resources/qml/hifi/tablet/Edit.qml @@ -1,5 +1,5 @@ import QtQuick 2.7 -import QtQuick.Controls 2.2 +import QtQuick.Controls 2.3 StackView { id: editRoot @@ -8,6 +8,9 @@ StackView { signal sendToScript(var message); topPadding: 40 + leftPadding: 0 + rightPadding: 0 + bottomPadding: 0 property var itemProperties: {"y": editRoot.topPadding, "width": editRoot.availableWidth, @@ -20,6 +23,7 @@ StackView { color: "#404040" //default background color EditTabView { id: tab + anchors.fill: parent currentIndex: -1 onCurrentIndexChanged: { editRoot.replace(null, tab.itemAt(currentIndex).visualItem, diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 61e22c0400..c156b80388 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -46,8 +46,6 @@ Window { // type should only consist of logic sized areas, with nothing drawn (although the // default value for the frame property does include visual decorations) property var pane: Item { - property bool isScrolling: Qt.binding(function() { return scrollView.contentHeight > scrollView.height; }); - property int contentWidth: scrollView.width property int scrollHeight: scrollView.height @@ -81,15 +79,16 @@ Window { contentItem.children: [ content ] contentHeight: content.height boundsBehavior: Flickable.StopAtBounds + property bool isScrolling: (contentHeight - height) > 10 ? true : false clip: true - anchors.rightMargin: parent.isScrolling ? verticalScrollWidth : 0 + anchors.rightMargin: isScrolling ? verticalScrollWidth : 0 anchors.fill: parent anchors.bottomMargin: footerPane.height ScrollBar.vertical: ScrollBar { - policy: scrollView.contentHeight > scrollView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff + policy: scrollView.isScrolling ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff parent: scrollView.parent anchors.top: scrollView.top anchors.right: scrollView.right From bd0e13463dfe354dc8fcf11eb2998f74fac98096 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 29 Mar 2018 17:06:23 -0400 Subject: [PATCH 045/109] Fix on unpackDeferredPosition --- libraries/render-utils/src/DeferredBufferRead.slh | 3 +-- libraries/render-utils/src/DeferredTransform.slh | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh index 3cbed3fcef..1b6a48aff5 100644 --- a/libraries/render-utils/src/DeferredBufferRead.slh +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -127,9 +127,8 @@ vec4 unpackDeferredPosition(DeferredFrameTransform deferredTransform, float dept } texcoord.x *= 2.0; } - float Zeye = evalZeyeFromZdb(depthValue); - return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0); + return vec4(evalEyePositionFromZdb(side, depthValue, texcoord), 1.0); } vec4 unpackDeferredPositionFromZeye(vec2 texcoord) { diff --git a/libraries/render-utils/src/DeferredTransform.slh b/libraries/render-utils/src/DeferredTransform.slh index 5fccbd6a99..59ba0a1b36 100644 --- a/libraries/render-utils/src/DeferredTransform.slh +++ b/libraries/render-utils/src/DeferredTransform.slh @@ -123,7 +123,6 @@ float evalZeyeFromZdb(float depth) { } vec3 evalEyeNormal(vec3 C) { - //return normalize(cross(dFdy(C), dFdx(C))); return normalize(cross(dFdx(C), dFdy(C))); } From 6f7a1eaefae51729c26b8bd7d9e58302b5a438d5 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 29 Mar 2018 18:05:43 -0400 Subject: [PATCH 046/109] Fixed correct inverse projection matrix when computing from Zeye --- .../render-utils/src/DeferredTransform.slh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libraries/render-utils/src/DeferredTransform.slh b/libraries/render-utils/src/DeferredTransform.slh index 59ba0a1b36..6b0e1cd642 100644 --- a/libraries/render-utils/src/DeferredTransform.slh +++ b/libraries/render-utils/src/DeferredTransform.slh @@ -122,16 +122,12 @@ float evalZeyeFromZdb(float depth) { return frameTransform._depthInfo.x / (depth * frameTransform._depthInfo.y + frameTransform._depthInfo.z); } -vec3 evalEyeNormal(vec3 C) { - return normalize(cross(dFdx(C), dFdy(C))); +float evalZdbFromZeye(float Zeye) { + return (frameTransform._depthInfo.x - Zeye * frameTransform._depthInfo.z) / (Zeye * frameTransform._depthInfo.y); } -vec3 evalEyePositionFromZeye(int side, float Zeye, vec2 texcoord) { - // compute the view space position using the depth - // basically manually pick the proj matrix components to do the inverse - float Xe = (-Zeye * (texcoord.x * 2.0 - 1.0) - Zeye * frameTransform._projection[side][2][0] - frameTransform._projection[side][3][0]) / frameTransform._projection[side][0][0]; - float Ye = (-Zeye * (texcoord.y * 2.0 - 1.0) - Zeye * frameTransform._projection[side][2][1] - frameTransform._projection[side][3][1]) / frameTransform._projection[side][1][1]; - return vec3(Xe, Ye, Zeye); +vec3 evalEyeNormal(vec3 C) { + return normalize(cross(dFdx(C), dFdy(C))); } vec3 evalEyePositionFromZdb(int side, float Zdb, vec2 texcoord) { @@ -142,6 +138,11 @@ vec3 evalEyePositionFromZdb(int side, float Zdb, vec2 texcoord) { return eyePos.xyz / eyePos.w; } +vec3 evalEyePositionFromZeye(int side, float Zeye, vec2 texcoord) { + float Zdb = evalZdbFromZeye(Zeye); + return evalEyePositionFromZdb(side, Zdb, texcoord); +} + ivec2 getPixelPosTexcoordPosAndSide(in vec2 glFragCoord, out ivec2 pixelPos, out vec2 texcoordPos, out ivec4 stereoSide) { ivec2 fragPos = ivec2(glFragCoord.xy); From 02cf15d1155a8b11e69f7960ba8aff0787ef1e03 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Fri, 30 Mar 2018 10:06:27 -0400 Subject: [PATCH 047/109] Lightclusters no unpack position from zdb --- libraries/render-utils/src/DeferredBufferRead.slh | 10 ++++++++-- .../src/lightClusters_drawClusterContent.slf | 2 +- .../src/lightClusters_drawClusterFromDepth.slf | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh index 1b6a48aff5..f7ab0957cc 100644 --- a/libraries/render-utils/src/DeferredBufferRead.slh +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -118,7 +118,7 @@ DeferredFragment unpackDeferredFragmentNoPositionNoAmbient(vec2 texcoord) { <@include DeferredTransform.slh@> <$declareDeferredFrameTransform()$> -vec4 unpackDeferredPosition(DeferredFrameTransform deferredTransform, float depthValue, vec2 texcoord) { +vec4 unpackDeferredPosition(float depthValue, vec2 texcoord) { int side = 0; if (isStereo()) { if (texcoord.x > 0.5) { @@ -131,6 +131,12 @@ vec4 unpackDeferredPosition(DeferredFrameTransform deferredTransform, float dept return vec4(evalEyePositionFromZdb(side, depthValue, texcoord), 1.0); } +// This method to unpack position is fastesst +vec4 unpackDeferredPositionFromZdb(vec2 texcoord) { + float Zdb = texture(depthMap, texcoord).x; + return unpackDeferredPosition(Zdb, texcoord); +} + vec4 unpackDeferredPositionFromZeye(vec2 texcoord) { float Zeye = -texture(linearZeyeMap, texcoord).x; int side = 0; @@ -151,7 +157,7 @@ DeferredFragment unpackDeferredFragment(DeferredFrameTransform deferredTransform DeferredFragment frag = unpackDeferredFragmentNoPosition(texcoord); frag.depthVal = depthValue; - frag.position = unpackDeferredPosition(deferredTransform, frag.depthVal, texcoord); + frag.position = unpackDeferredPosition(frag.depthVal, texcoord); return frag; } diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slf b/libraries/render-utils/src/lightClusters_drawClusterContent.slf index 739709418d..d4d97c5b16 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slf @@ -32,7 +32,7 @@ void main(void) { // Grab the fragment data from the uv vec2 texCoord = varTexCoord0.st; - vec4 fragEyePos = unpackDeferredPositionFromZeye(texCoord); + vec4 fragEyePos = unpackDeferredPositionFromZdb(texCoord); vec4 fragWorldPos = getViewInverse() * fragEyePos; // From frag world pos find the cluster diff --git a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf index ee2e6e0ccc..c51d45ed44 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf @@ -29,7 +29,7 @@ void main(void) { // Grab the fragment data from the uv vec2 texCoord = varTexCoord0.st; - vec4 fragEyePos = unpackDeferredPositionFromZeye(texCoord); + vec4 fragEyePos = unpackDeferredPositionFromZdb(texCoord); vec4 fragWorldPos = getViewInverse() * fragEyePos; // From frag world pos find the cluster From 1629756d53ebf4a1d98a59258fdcb31c75faa24e Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 3 Apr 2018 18:08:43 -0700 Subject: [PATCH 048/109] Adding more budget options for memory texture --- interface/src/Menu.cpp | 9 +++++++++ interface/src/Menu.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6c071defff..df7546cd33 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -447,6 +447,9 @@ Menu::Menu() { textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture512MB, 0, false)); textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture1024MB, 0, false)); textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture2048MB, 0, false)); + textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture4096MB, 0, false)); + textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture6144MB, 0, false)); + textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture8192MB, 0, false)); connect(textureGroup, &QActionGroup::triggered, [textureGroup] { auto checked = textureGroup->checkedAction(); auto text = checked->text(); @@ -463,6 +466,12 @@ Menu::Menu() { newMaxTextureMemory = MB_TO_BYTES(1024); } else if (MenuOption::RenderMaxTexture2048MB == text) { newMaxTextureMemory = MB_TO_BYTES(2048); + } else if (MenuOption::RenderMaxTexture4096MB == text) { + newMaxTextureMemory = MB_TO_BYTES(4096); + } else if (MenuOption::RenderMaxTexture6144MB == text) { + newMaxTextureMemory = MB_TO_BYTES(6144); + } else if (MenuOption::RenderMaxTexture8192MB == text) { + newMaxTextureMemory = MB_TO_BYTES(8192); } gpu::Texture::setAllowedGPUMemoryUsage(newMaxTextureMemory); }); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index cf9eed1a27..4d418a16d2 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -155,6 +155,10 @@ namespace MenuOption { const QString RenderMaxTexture512MB = "512 MB"; const QString RenderMaxTexture1024MB = "1024 MB"; const QString RenderMaxTexture2048MB = "2048 MB"; + const QString RenderMaxTexture3072MB = "3072 MB"; + const QString RenderMaxTexture4096MB = "4096 MB"; + const QString RenderMaxTexture6144MB = "6144 MB"; + const QString RenderMaxTexture8192MB = "8192 MB"; const QString RenderResolution = "Scale Resolution"; const QString RenderResolutionOne = "1"; const QString RenderResolutionTwoThird = "2/3"; From f9bcd23463bc7dfa2cfb0041e22339087d7b6a8b Mon Sep 17 00:00:00 2001 From: WolfGang Date: Wed, 4 Apr 2018 17:28:55 +0100 Subject: [PATCH 049/109] make subimage update the image anchors --- interface/resources/qml/hifi/overlays/ImageOverlay.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/qml/hifi/overlays/ImageOverlay.qml b/interface/resources/qml/hifi/overlays/ImageOverlay.qml index cbcf6c7910..0171ac7b2c 100644 --- a/interface/resources/qml/hifi/overlays/ImageOverlay.qml +++ b/interface/resources/qml/hifi/overlays/ImageOverlay.qml @@ -62,6 +62,7 @@ Overlay { case "height": image.ySize = value; break; } } + image.resizer.start(); } function updatePropertiesFromScript(properties) { From 09ced247105e1ff4236b9554c46dd8f49bb0d4a0 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 4 Apr 2018 11:05:25 -0700 Subject: [PATCH 050/109] hide desktop windows when switching into HMD mode --- interface/resources/qml/desktop/Desktop.qml | 10 ++++++++++ libraries/ui/src/OffscreenUi.cpp | 7 +++++++ libraries/ui/src/OffscreenUi.h | 1 + libraries/ui/src/ui/TabletScriptingInterface.cpp | 2 ++ 4 files changed, 20 insertions(+) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index e7c68b2a47..3535a49880 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -323,6 +323,16 @@ FocusScope { return false; } + function hideDesktopWindows() { + for (var index = 0; index < desktop.visibleChildren.length; index++) { + var child = desktop.visibleChildren[index]; + if (child.topLevelWindow && child.hasOwnProperty("modality")) { + console.log(child); + child.setShown(false); + } + } + } + function setPinned(newPinned) { pinned = newPinned } diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 7a938f39c8..a1d09139e3 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -154,6 +154,13 @@ void OffscreenUi::show(const QUrl& url, const QString& name, std::function f) { QQuickItem* item = getRootItem()->findChild(name); if (!item) { diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index cb8ee29068..26f9f58dd5 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -60,6 +60,7 @@ public: void createDesktop(const QUrl& url); void show(const QUrl& url, const QString& name, std::function f = [](QQmlContext*, QObject*) {}); void hide(const QString& name); + void hideDesktopWindows(); bool isVisible(const QString& name); void toggle(const QUrl& url, const QString& name, std::function f = [](QQmlContext*, QObject*) {}); bool shouldSwallowShortcut(QEvent* event); diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 0191baca5e..a079609bb7 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -387,6 +387,8 @@ void TabletProxy::setToolbarMode(bool toolbarMode) { offscreenUi->hide("RunningScripts"); _showRunningScripts = true; } + + offscreenUi->hideDesktopWindows(); // destroy desktop window if (_desktopWindow) { _desktopWindow->deleteLater(); From 475a3a29acdd36fe72270dde3f23cd9d3ac4a3ca Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 4 Apr 2018 11:14:53 -0700 Subject: [PATCH 051/109] remvoe debug statement --- interface/resources/qml/desktop/Desktop.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 3535a49880..df15c8b5fc 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -327,7 +327,6 @@ FocusScope { for (var index = 0; index < desktop.visibleChildren.length; index++) { var child = desktop.visibleChildren[index]; if (child.topLevelWindow && child.hasOwnProperty("modality")) { - console.log(child); child.setShown(false); } } From 2545e67b143e90b098519c359bd6113e2784cbce Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 4 Apr 2018 12:27:41 -0700 Subject: [PATCH 052/109] set lastEditedBy in local tree whenever a script adds or edits an entity --- .../entities/src/EntityScriptingInterface.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 2e9b386ba5..37e26a422b 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -241,14 +241,18 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties _activityTracking.addedEntityCount++; + auto nodeList = DependencyManager::get(); + auto sessionID = nodeList->getSessionUUID(); + EntityItemProperties propertiesWithSimID = properties; if (clientOnly) { - auto nodeList = DependencyManager::get(); - const QUuid myNodeID = nodeList->getSessionUUID(); + const QUuid myNodeID = sessionID; propertiesWithSimID.setClientOnly(clientOnly); propertiesWithSimID.setOwningAvatarID(myNodeID); } + propertiesWithSimID.setLastEditedBy(sessionID); + bool scalesWithParent = propertiesWithSimID.getScalesWithParent(); propertiesWithSimID = convertPropertiesFromScriptSemantics(propertiesWithSimID, scalesWithParent); @@ -308,6 +312,11 @@ QUuid EntityScriptingInterface::addModelEntity(const QString& name, const QStrin if (!textures.isEmpty()) { properties.setTextures(textures); } + + auto nodeList = DependencyManager::get(); + auto sessionID = nodeList->getSessionUUID(); + properties.setLastEditedBy(sessionID); + return addEntity(properties); } @@ -363,7 +372,11 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& _activityTracking.editedEntityCount++; + auto nodeList = DependencyManager::get(); + auto sessionID = nodeList->getSessionUUID(); + EntityItemProperties properties = scriptSideProperties; + properties.setLastEditedBy(sessionID); EntityItemID entityID(id); if (!_entityTree) { @@ -379,7 +392,6 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& return; } - auto nodeList = DependencyManager::get(); if (entity->getClientOnly() && entity->getOwningAvatarID() != nodeList->getSessionUUID()) { // don't edit other avatar's avatarEntities return; From 787127b149d35cae3565b87ca3e94e47c7a7149e Mon Sep 17 00:00:00 2001 From: WolfGang Date: Wed, 4 Apr 2018 22:10:54 +0100 Subject: [PATCH 053/109] move subImage recalculation to it's own method --- .../qml/hifi/overlays/ImageOverlay.qml | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/hifi/overlays/ImageOverlay.qml b/interface/resources/qml/hifi/overlays/ImageOverlay.qml index 0171ac7b2c..c1ed166769 100644 --- a/interface/resources/qml/hifi/overlays/ImageOverlay.qml +++ b/interface/resources/qml/hifi/overlays/ImageOverlay.qml @@ -20,17 +20,7 @@ Overlay { repeat: false running: false onTriggered: { - if (image.xSize === 0) { - image.xSize = image.sourceSize.width - image.xStart; - } - if (image.ySize === 0) { - image.ySize = image.sourceSize.height - image.yStart; - } - - image.anchors.leftMargin = -image.xStart * root.width / image.xSize; - image.anchors.topMargin = -image.yStart * root.height / image.ySize; - image.anchors.rightMargin = (image.xStart + image.xSize - image.sourceSize.width) * root.width / image.xSize; - image.anchors.bottomMargin = (image.yStart + image.ySize - image.sourceSize.height) * root.height / image.ySize; + recalculateMargins(); } } @@ -44,6 +34,20 @@ Overlay { anchors.fill: parent } + function recalculateMargins() { + if (image.xSize === 0) { + image.xSize = image.sourceSize.width - image.xStart; + } + if (image.ySize === 0) { + image.ySize = image.sourceSize.height - image.yStart; + } + + image.anchors.leftMargin = -image.xStart * root.width / image.xSize; + image.anchors.topMargin = -image.yStart * root.height / image.ySize; + image.anchors.rightMargin = (image.xStart + image.xSize - image.sourceSize.width) * root.width / image.xSize; + image.anchors.bottomMargin = (image.yStart + image.ySize - image.sourceSize.height) * root.height / image.ySize; + } + ColorOverlay { id: color anchors.fill: image @@ -62,7 +66,7 @@ Overlay { case "height": image.ySize = value; break; } } - image.resizer.start(); + recalculateMargins(); } function updatePropertiesFromScript(properties) { From 895023ca4b5e114ca12e3d3946aeea2f82282bb9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Mar 2018 17:43:14 -0800 Subject: [PATCH 054/109] Fix unprotected tree traversals --- .../src/entities/EntityServer.cpp | 45 ++++++++++++------- .../src/octree/OctreeSendThread.cpp | 4 +- libraries/entities/src/EntityTree.cpp | 41 +++++++++++------ .../entities/src/SimpleEntitySimulation.cpp | 9 +++- 4 files changed, 65 insertions(+), 34 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index d2bcbf2886..e3aca52ee5 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -363,7 +363,9 @@ void EntityServer::nodeAdded(SharedNodePointer node) { void EntityServer::nodeKilled(SharedNodePointer node) { EntityTreePointer tree = std::static_pointer_cast(_tree); - tree->deleteDescendantsOfAvatar(node->getUUID()); + tree->withWriteLock([&] { + tree->deleteDescendantsOfAvatar(node->getUUID()); + }); tree->forgetAvatarID(node->getUUID()); OctreeServer::nodeKilled(node); } @@ -451,8 +453,6 @@ void EntityServer::domainSettingsRequestFailed() { void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << "Starting Dynamic Domain Verification..."; - QString thisDomainID = DependencyManager::get()->getDomainID().remove(QRegExp("\\{|\\}")); - EntityTreePointer tree = std::static_pointer_cast(_tree); QHash localMap(tree->getEntityCertificateIDMap()); @@ -460,15 +460,19 @@ void EntityServer::startDynamicDomainVerification() { qCDebug(entities) << localMap.size() << "entities in _entityCertificateIDMap"; while (i.hasNext()) { i.next(); + const auto& certificateID = i.key(); + const auto& entityID = i.value(); - EntityItemPointer entity = tree->findEntityByEntityItemID(i.value()); + EntityItemPointer entity = tree->findEntityByEntityItemID(entityID); if (entity) { if (!entity->getProperties().verifyStaticCertificateProperties()) { - qCDebug(entities) << "During Dynamic Domain Verification, a certified entity with ID" << i.value() << "failed" + qCDebug(entities) << "During Dynamic Domain Verification, a certified entity with ID" << entityID << "failed" << "static certificate verification."; // Delete the entity if it doesn't pass static certificate verification - tree->deleteEntity(i.value(), true); + tree->withWriteLock([&] { + tree->deleteEntity(entityID, true); + }); } else { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest networkRequest; @@ -477,39 +481,46 @@ void EntityServer::startDynamicDomainVerification() { QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); QJsonObject request; - request["certificate_id"] = i.key(); + request["certificate_id"] = certificateID; networkRequest.setUrl(requestURL); - QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + + connect(networkReply, &QNetworkReply::finished, this, [this, entityID, networkReply] { + EntityTreePointer tree = std::static_pointer_cast(_tree); - connect(networkReply, &QNetworkReply::finished, [=]() { QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); jsonObject = jsonObject["data"].toObject(); if (networkReply->error() == QNetworkReply::NoError) { + QString thisDomainID = DependencyManager::get()->getDomainID().remove(QRegExp("\\{|\\}")); if (jsonObject["domain_id"].toString() != thisDomainID) { + EntityItemPointer entity = tree->findEntityByEntityItemID(entityID); if (entity->getAge() > (_MAXIMUM_DYNAMIC_DOMAIN_VERIFICATION_TIMER_MS/MSECS_PER_SECOND)) { qCDebug(entities) << "Entity's cert's domain ID" << jsonObject["domain_id"].toString() - << "doesn't match the current Domain ID" << thisDomainID << "; deleting entity" << i.value(); - tree->deleteEntity(i.value(), true); + << "doesn't match the current Domain ID" << thisDomainID << "; deleting entity" << entityID; + tree->withWriteLock([&] { + tree->deleteEntity(entityID, true); + }); } else { - qCDebug(entities) << "Entity failed dynamic domain verification, but was created too recently to necessitate deletion:" << i.value(); + qCDebug(entities) << "Entity failed dynamic domain verification, but was created too recently to necessitate deletion:" << entityID; } } else { - qCDebug(entities) << "Entity passed dynamic domain verification:" << i.value(); + qCDebug(entities) << "Entity passed dynamic domain verification:" << entityID; } } else { - qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << i.value() + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << entityID << "More info:" << jsonObject; - tree->deleteEntity(i.value(), true); + tree->withWriteLock([&] { + tree->deleteEntity(entityID, true); + }); } networkReply->deleteLater(); }); } } else { - qCWarning(entities) << "During DDV, an entity with ID" << i.value() << "was NOT found in the Entity Tree!"; + qCWarning(entities) << "During DDV, an entity with ID" << entityID << "was NOT found in the Entity Tree!"; } } diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index d5b9da7353..715e83f403 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -400,7 +400,9 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* if (shouldTraverseAndSend(nodeData)) { quint64 start = usecTimestampNow(); - traverseTreeAndSendContents(node, nodeData, viewFrustumChanged, isFullScene); + _myServer->getOctree()->withReadLock([&]{ + traverseTreeAndSendContents(node, nodeData, viewFrustumChanged, isFullScene); + }); // Here's where we can/should allow the server to send other data... // send the environment packet diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 2cf66911a4..03258cd52d 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1151,7 +1151,9 @@ void EntityTree::startChallengeOwnershipTimer(const EntityItemID& entityItemID) }); connect(_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { qCDebug(entities) << "Ownership challenge timed out, deleting entity" << entityItemID; - deleteEntity(entityItemID, true); + withWriteLock([&] { + deleteEntity(entityItemID, true); + }); if (_challengeOwnershipTimeoutTimer) { _challengeOwnershipTimeoutTimer->stop(); _challengeOwnershipTimeoutTimer->deleteLater(); @@ -1259,7 +1261,9 @@ void EntityTree::sendChallengeOwnershipPacket(const QString& certID, const QStri if (text == "") { qCDebug(entities) << "CRITICAL ERROR: Couldn't compute nonce. Deleting entity..."; - deleteEntity(entityItemID, true); + withWriteLock([&] { + deleteEntity(entityItemID, true); + }); } else { qCDebug(entities) << "Challenging ownership of Cert ID" << certID; // 2. Send the nonce to the rezzing avatar's node @@ -1322,8 +1326,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt request["certificate_id"] = certID; networkRequest.setUrl(requestURL); - QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); connect(networkReply, &QNetworkReply::finished, [=]() { QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); @@ -1332,14 +1335,20 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt if (networkReply->error() == QNetworkReply::NoError) { if (!jsonObject["invalid_reason"].toString().isEmpty()) { qCDebug(entities) << "invalid_reason not empty, deleting entity" << entityItemID; - deleteEntity(entityItemID, true); + withWriteLock([&] { + deleteEntity(entityItemID, true); + }); } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { qCDebug(entities) << "'transfer_status' is 'failed', deleting entity" << entityItemID; - deleteEntity(entityItemID, true); + withWriteLock([&] { + deleteEntity(entityItemID, true); + }); } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { if (isRetryingValidation) { qCDebug(entities) << "'transfer_status' is 'pending' after retry, deleting entity" << entityItemID; - deleteEntity(entityItemID, true); + withWriteLock([&] { + deleteEntity(entityItemID, true); + }); } else { if (thread() != QThread::currentThread()) { QMetaObject::invokeMethod(this, "startPendingTransferStatusTimer", @@ -1362,7 +1371,9 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt } else { qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "; deleting entity" << entityItemID << "More info:" << jsonObject; - deleteEntity(entityItemID, true); + withWriteLock([&] { + deleteEntity(entityItemID, true); + }); } networkReply->deleteLater(); @@ -1796,9 +1807,9 @@ void EntityTree::addToNeedsParentFixupList(EntityItemPointer entity) { void EntityTree::update(bool simulate) { PROFILE_RANGE(simulation_physics, "UpdateTree"); - fixupNeedsParentFixups(); - if (simulate && _simulation) { - withWriteLock([&] { + withWriteLock([&] { + fixupNeedsParentFixups(); + if (simulate && _simulation) { _simulation->updateEntities(); { PROFILE_RANGE(simulation_physics, "Deletes"); @@ -1816,8 +1827,8 @@ void EntityTree::update(bool simulate) { deleteEntities(idsToDelete, true); } } - }); - } + } + }); } quint64 EntityTree::getAdjustedConsiderSince(quint64 sinceTime) { @@ -2286,7 +2297,9 @@ bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer QScriptEngine scriptEngine; RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine, skipDefaultValues, skipThoseWithBadParents, _myAvatar); - recurseTreeWithOperator(&theOperator); + withReadLock([&] { + recurseTreeWithOperator(&theOperator); + }); return true; } diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index 3203c2968c..4c01269ed5 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -42,8 +42,13 @@ void SimpleEntitySimulation::clearOwnership(const QUuid& ownerID) { // remove ownership and dirty all the tree elements that contain the it entity->clearSimulationOwnership(); entity->markAsChangedOnServer(); - DirtyOctreeElementOperator op(entity->getElement()); - getEntityTree()->recurseTreeWithOperator(&op); + if (auto element = entity->getElement()) { + auto tree = getEntityTree(); + tree->withReadLock([&] { + DirtyOctreeElementOperator op(element); + tree->recurseTreeWithOperator(&op); + }); + } } else { ++itemItr; } From 31783726a8f7fae4b55c1a31b2143058760a097d Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 4 Apr 2018 16:30:06 -0700 Subject: [PATCH 055/109] fix toolbar disappearing --- interface/resources/qml/desktop/Desktop.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index df15c8b5fc..c0709ad033 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -327,7 +327,10 @@ FocusScope { for (var index = 0; index < desktop.visibleChildren.length; index++) { var child = desktop.visibleChildren[index]; if (child.topLevelWindow && child.hasOwnProperty("modality")) { - child.setShown(false); + var TOOLBAR_NAME = "com.highfidelity.interface.toolbar.system" + if (child.objectName !== TOOLBAR_NAME) { + child.setShown(false); + } } } } From 9ec10bbb7ed406869a25e61f3af8a8d13c214925 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 16 Mar 2018 19:50:03 +0300 Subject: [PATCH 056/109] Make keyboard's 'raisedHeight' to include 'mirror text' height note: this is necessary becasue all the dialogs rely on 'raisedHeight', so without 'mirror text' they will use wrong keyboard geometry during calculations --- interface/resources/qml/controls-uit/Keyboard.qml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/controls-uit/Keyboard.qml b/interface/resources/qml/controls-uit/Keyboard.qml index ea76d44aaa..9d4fd33022 100644 --- a/interface/resources/qml/controls-uit/Keyboard.qml +++ b/interface/resources/qml/controls-uit/Keyboard.qml @@ -26,15 +26,17 @@ Rectangle { readonly property int keyboardRowHeight: 50 readonly property int keyboardWidth: 480 + readonly property int keyboardHeight: 200 readonly property int mirrorTextHeight: keyboardRowHeight property bool password: false property alias mirroredText: mirrorText.text property bool showMirrorText: true - readonly property int raisedHeight: 200 - height: enabled && raised ? raisedHeight + (showMirrorText ? keyboardRowHeight : 0) : 0 + readonly property int raisedHeight: keyboardHeight + (showMirrorText ? keyboardRowHeight : 0) + + height: enabled && raised ? raisedHeight : 0 visible: enabled && raised property bool shiftMode: false @@ -158,7 +160,7 @@ Rectangle { id: keyboardRect y: showMirrorText ? mirrorTextHeight : 0 width: keyboardWidth - height: raisedHeight + height: keyboardHeight color: "#252525" anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom @@ -167,7 +169,7 @@ Rectangle { Column { id: columnAlpha width: keyboardWidth - height: raisedHeight + height: keyboardHeight visible: !numeric Row { @@ -259,7 +261,7 @@ Rectangle { Column { id: columnNumeric width: keyboardWidth - height: raisedHeight + height: keyboardHeight visible: numeric Row { From 995d678d2037a52b31196582b998ba3317bbb31a Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 6 Apr 2018 02:51:22 +0300 Subject: [PATCH 057/109] fix for closed query dialogs auto-reopening (FB13962 Import Entity URL Dialogue Box Will not Disappear) Signed-off-by: Alexander Ivash --- interface/resources/qml/dialogs/CustomQueryDialog.qml | 4 ++++ interface/resources/qml/dialogs/QueryDialog.qml | 4 ++++ interface/resources/qml/windows/Fadable.qml | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/dialogs/CustomQueryDialog.qml b/interface/resources/qml/dialogs/CustomQueryDialog.qml index 6e1bb4b309..6ce4722d04 100644 --- a/interface/resources/qml/dialogs/CustomQueryDialog.qml +++ b/interface/resources/qml/dialogs/CustomQueryDialog.qml @@ -272,6 +272,8 @@ ModalWindow { root.canceled(); // FIXME we are leaking memory to avoid a crash // root.destroy(); + + root.disableFade = true visible = false; } } @@ -296,6 +298,8 @@ ModalWindow { root.selected(root.result); // FIXME we are leaking memory to avoid a crash // root.destroy(); + + root.disableFade = true visible = false; } } diff --git a/interface/resources/qml/dialogs/QueryDialog.qml b/interface/resources/qml/dialogs/QueryDialog.qml index 6f05179bd5..ec62f16087 100644 --- a/interface/resources/qml/dialogs/QueryDialog.qml +++ b/interface/resources/qml/dialogs/QueryDialog.qml @@ -171,6 +171,8 @@ ModalWindow { root.canceled(); // FIXME we are leaking memory to avoid a crash // root.destroy(); + + root.disableFade = true visible = false; } } @@ -183,6 +185,8 @@ ModalWindow { root.selected(root.result); // FIXME we are leaking memory to avoid a crash // root.destroy(); + + root.disableFade = true visible = false; } } diff --git a/interface/resources/qml/windows/Fadable.qml b/interface/resources/qml/windows/Fadable.qml index 4d506755f2..52d2264e7d 100644 --- a/interface/resources/qml/windows/Fadable.qml +++ b/interface/resources/qml/windows/Fadable.qml @@ -39,7 +39,7 @@ FocusScope { // If someone directly set the visibility to false // toggle it back on and use the targetVisible flag to transition // via fading. - if ((!visible && fadeTargetProperty != 0.0) || (visible && fadeTargetProperty == 0.0)) { + if (!disableFade && ((!visible && fadeTargetProperty != 0.0) || (visible && fadeTargetProperty == 0.0))) { var target = visible; visible = !visible; fadeTargetProperty = target ? 1.0 : 0.0; From 44ea5a2e84460c227e9f52a5c43be2d30f94ffa7 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 2 Apr 2018 17:18:38 -0700 Subject: [PATCH 058/109] add etc2/eac support --- .../src/gpu/gl/GLTexelFormat.cpp | 92 ++++++++++++++++++- .../src/gpu/gl41/GL41BackendTexture.cpp | 22 +++++ .../src/gpu/gl45/GL45BackendTexture.cpp | 20 ++++ .../src/gpu/gles/GLESBackendTexture.cpp | 48 +++++++++- libraries/gpu/src/gpu/Format.cpp | 25 +++-- libraries/gpu/src/gpu/Format.h | 46 ++++++++-- libraries/gpu/src/gpu/Texture_ktx.cpp | 78 +++++++++++----- .../graphics/src/graphics/GpuHelpers.cpp | 11 +++ libraries/image/src/image/Image.cpp | 49 +++++++--- libraries/ktx/src/khronos/KHR.h | 21 +++++ 10 files changed, 355 insertions(+), 57 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp index 99a9afb4c4..4d94f8d8e7 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLTexelFormat.cpp @@ -370,7 +370,36 @@ GLenum GLTexelFormat::evalGLTexelFormatInternal(const gpu::Element& dstFormat) { case gpu::COMPRESSED_BC7_SRGBA: result = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; break; - + case gpu::COMPRESSED_ETC2_RGB: + result = GL_COMPRESSED_RGB8_ETC2; + break; + case gpu::COMPRESSED_ETC2_SRGB: + result = GL_COMPRESSED_SRGB8_ETC2; + break; + case gpu::COMPRESSED_ETC2_RGB_PUNCHTHROUGH_ALPHA: + result = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + case gpu::COMPRESSED_ETC2_SRGB_PUNCHTHROUGH_ALPHA: + result = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + case gpu::COMPRESSED_ETC2_RGBA: + result = GL_COMPRESSED_RGBA8_ETC2_EAC; + break; + case gpu::COMPRESSED_ETC2_SRGBA: + result = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + break; + case gpu::COMPRESSED_EAC_RED: + result = GL_COMPRESSED_R11_EAC; + break; + case gpu::COMPRESSED_EAC_RED_SIGNED: + result = GL_COMPRESSED_SIGNED_R11_EAC; + break; + case gpu::COMPRESSED_EAC_XY: + result = GL_COMPRESSED_RG11_EAC; + break; + case gpu::COMPRESSED_EAC_XY_SIGNED: + result = GL_COMPRESSED_SIGNED_RG11_EAC; + break; default: qCWarning(gpugllogging) << "Unknown combination of texel format"; } @@ -531,6 +560,36 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E case gpu::COMPRESSED_BC7_SRGBA: texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; break; + case gpu::COMPRESSED_ETC2_RGB: + texel.internalFormat = GL_COMPRESSED_RGB8_ETC2; + break; + case gpu::COMPRESSED_ETC2_SRGB: + texel.internalFormat = GL_COMPRESSED_SRGB8_ETC2; + break; + case gpu::COMPRESSED_ETC2_RGB_PUNCHTHROUGH_ALPHA: + texel.internalFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + case gpu::COMPRESSED_ETC2_SRGB_PUNCHTHROUGH_ALPHA: + texel.internalFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + case gpu::COMPRESSED_ETC2_RGBA: + texel.internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; + break; + case gpu::COMPRESSED_ETC2_SRGBA: + texel.internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + break; + case gpu::COMPRESSED_EAC_RED: + texel.internalFormat = GL_COMPRESSED_R11_EAC; + break; + case gpu::COMPRESSED_EAC_RED_SIGNED: + texel.internalFormat = GL_COMPRESSED_SIGNED_R11_EAC; + break; + case gpu::COMPRESSED_EAC_XY: + texel.internalFormat = GL_COMPRESSED_RG11_EAC; + break; + case gpu::COMPRESSED_EAC_XY_SIGNED: + texel.internalFormat = GL_COMPRESSED_SIGNED_RG11_EAC; + break; default: qCWarning(gpugllogging) << "Unknown combination of texel format"; } @@ -895,7 +954,36 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E case gpu::COMPRESSED_BC7_SRGBA: texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; break; - + case gpu::COMPRESSED_ETC2_RGB: + texel.internalFormat = GL_COMPRESSED_RGB8_ETC2; + break; + case gpu::COMPRESSED_ETC2_SRGB: + texel.internalFormat = GL_COMPRESSED_SRGB8_ETC2; + break; + case gpu::COMPRESSED_ETC2_RGB_PUNCHTHROUGH_ALPHA: + texel.internalFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + case gpu::COMPRESSED_ETC2_SRGB_PUNCHTHROUGH_ALPHA: + texel.internalFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + case gpu::COMPRESSED_ETC2_RGBA: + texel.internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; + break; + case gpu::COMPRESSED_ETC2_SRGBA: + texel.internalFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + break; + case gpu::COMPRESSED_EAC_RED: + texel.internalFormat = GL_COMPRESSED_R11_EAC; + break; + case gpu::COMPRESSED_EAC_RED_SIGNED: + texel.internalFormat = GL_COMPRESSED_SIGNED_R11_EAC; + break; + case gpu::COMPRESSED_EAC_XY: + texel.internalFormat = GL_COMPRESSED_RG11_EAC; + break; + case gpu::COMPRESSED_EAC_XY_SIGNED: + texel.internalFormat = GL_COMPRESSED_SIGNED_RG11_EAC; + break; default: qCWarning(gpugllogging) << "Unknown combination of texel format"; } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 61c3da391b..09e70a3bb2 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -115,6 +115,17 @@ Size GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: + // TODO: confirm that these work on mac + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: glCompressedTexSubImage2D(_target, mip, 0, yOffset, size.x, size.y, internalFormat, static_cast(sourceSize), sourcePointer); break; @@ -133,6 +144,17 @@ Size GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: + // TODO: confirm that these work on mac + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: glCompressedTexSubImage2D(target, mip, 0, yOffset, size.x, size.y, internalFormat, static_cast(sourceSize), sourcePointer); break; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 5e64e1845e..47e516ff24 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -144,6 +144,16 @@ Size GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: glCompressedTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, internalFormat, static_cast(sourceSize), sourcePointer); break; @@ -160,6 +170,16 @@ Size GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: if (glCompressedTextureSubImage2DEXT) { auto target = GLTexture::CUBE_FACE_LAYOUT[face]; glCompressedTextureSubImage2DEXT(_id, target, mip, 0, yOffset, size.x, size.y, internalFormat, diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp index 6bc55a23d4..2009dc5dc9 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp @@ -20,9 +20,21 @@ using namespace gpu::gl; using namespace gpu::gles; bool GLESBackend::supportedTextureFormat(const gpu::Element& format) { - // FIXME distinguish between GLES and GL compressed formats after support - // for the former is added to gpu::Element - return !format.isCompressed(); + switch (format.getSemantic()) { + case gpu::Semantic::COMPRESSED_ETC2_RGB: + case gpu::Semantic::COMPRESSED_ETC2_SRGB: + case gpu::Semantic::COMPRESSED_ETC2_RGB_PUNCHTHROUGH_ALPHA: + case gpu::Semantic::COMPRESSED_ETC2_SRGB_PUNCHTHROUGH_ALPHA: + case gpu::Semantic::COMPRESSED_ETC2_RGBA: + case gpu::Semantic::COMPRESSED_ETC2_SRGBA: + case gpu::Semantic::COMPRESSED_EAC_RED: + case gpu::Semantic::COMPRESSED_EAC_RED_SIGNED: + case gpu::Semantic::COMPRESSED_EAC_XY: + case gpu::Semantic::COMPRESSED_EAC_XY_SIGNED: + return true; + default: + return !format.isCompressed(); + } } GLTexture* GLESBackend::syncGPUObject(const TexturePointer& texturePointer) { @@ -231,6 +243,29 @@ GLESFixedAllocationTexture::GLESFixedAllocationTexture(const std::weak_ptrgetStoredMipFormat(); - if (mipFormat == gpu::Element::COLOR_COMPRESSED_SRGB) { + if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_SRGB) { compressionOptions.setFormat(nvtt::Format_BC1); - } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_SRGBA_MASK) { + } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_SRGBA_MASK) { alphaMode = nvtt::AlphaMode_Transparency; compressionOptions.setFormat(nvtt::Format_BC1a); - } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_SRGBA) { + } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_SRGBA) { alphaMode = nvtt::AlphaMode_Transparency; compressionOptions.setFormat(nvtt::Format_BC3); - } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_RED) { + } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_RED) { compressionOptions.setFormat(nvtt::Format_BC4); - } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_XY) { + } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_XY) { compressionOptions.setFormat(nvtt::Format_BC5); - } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_SRGBA_HIGH) { + } else if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_SRGBA_HIGH) { alphaMode = nvtt::AlphaMode_Transparency; compressionOptions.setFormat(nvtt::Format_BC7); } else if (mipFormat == gpu::Element::COLOR_RGBA_32) { @@ -736,13 +738,21 @@ gpu::TexturePointer TextureUsage::process2DTextureColorFromImage(QImage&& srcIma gpu::Element formatMip; gpu::Element formatGPU; if (isColorTexturesCompressionEnabled()) { +#ifndef USE_GLES if (validAlpha) { // NOTE: This disables BC1a compression because it was producing odd artifacts on text textures // for the tutorial. Instead we use BC3 (which is larger) but doesn't produce the same artifacts). - formatGPU = gpu::Element::COLOR_COMPRESSED_SRGBA; + formatGPU = gpu::Element::COLOR_COMPRESSED_BCX_SRGBA; } else { - formatGPU = gpu::Element::COLOR_COMPRESSED_SRGB; + formatGPU = gpu::Element::COLOR_COMPRESSED_BCX_SRGB; } +#else + if (validAlpha) { + formatGPU = gpu::Element::COLOR_COMPRESSED_ETC2_SRGBA; + } else { + formatGPU = gpu::Element::COLOR_COMPRESSED_ETC2_SRGB; + } +#endif formatMip = formatGPU; } else { #ifdef USE_GLES @@ -869,8 +879,12 @@ gpu::TexturePointer TextureUsage::process2DTextureNormalMapFromImage(QImage&& sr gpu::Element formatMip = gpu::Element::VEC2NU8_XY; gpu::Element formatGPU = gpu::Element::VEC2NU8_XY; if (isNormalTexturesCompressionEnabled()) { - formatMip = gpu::Element::COLOR_COMPRESSED_XY; - formatGPU = gpu::Element::COLOR_COMPRESSED_XY; +#ifndef USE_GLES + formatGPU = gpu::Element::COLOR_COMPRESSED_BCX_XY; +#else + formatGPU = gpu::Element::COLOR_COMPRESSED_EAC_XY; +#endif + formatMip = formatGPU; } theTexture = gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)); @@ -903,8 +917,12 @@ gpu::TexturePointer TextureUsage::process2DTextureGrayscaleFromImage(QImage&& sr gpu::Element formatMip; gpu::Element formatGPU; if (isGrayscaleTexturesCompressionEnabled()) { - formatMip = gpu::Element::COLOR_COMPRESSED_RED; - formatGPU = gpu::Element::COLOR_COMPRESSED_RED; +#ifndef USE_GLES + formatGPU = gpu::Element::COLOR_COMPRESSED_BCX_RED; +#else + formatGPU = gpu::Element::COLOR_COMPRESSED_EAC_RED; +#endif + formatMip = formatGPU; } else { formatMip = gpu::Element::COLOR_R_8; formatGPU = gpu::Element::COLOR_R_8; @@ -1271,8 +1289,9 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(QImage&& srcI gpu::Element formatMip; gpu::Element formatGPU; if (isCubeTexturesCompressionEnabled()) { - formatMip = gpu::Element::COLOR_COMPRESSED_HDR_RGB; - formatGPU = gpu::Element::COLOR_COMPRESSED_HDR_RGB; + // TODO: gles: pick HDR ETC format + formatMip = gpu::Element::COLOR_COMPRESSED_BCX_HDR_RGB; + formatGPU = gpu::Element::COLOR_COMPRESSED_BCX_HDR_RGB; } else { formatMip = HDR_FORMAT; formatGPU = HDR_FORMAT; diff --git a/libraries/ktx/src/khronos/KHR.h b/libraries/ktx/src/khronos/KHR.h index cda22513ee..4ee893e4fc 100644 --- a/libraries/ktx/src/khronos/KHR.h +++ b/libraries/ktx/src/khronos/KHR.h @@ -358,6 +358,17 @@ namespace khronos { case InternalFormat::COMPRESSED_RG_RGTC2: // BC5 case InternalFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: // BC6 case InternalFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM: // BC7 + // ETC2 / EAC + case InternalFormat::COMPRESSED_RGB8_ETC2: + case InternalFormat::COMPRESSED_SRGB8_ETC2: + case InternalFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case InternalFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case InternalFormat::COMPRESSED_RGBA8_ETC2_EAC: + case InternalFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case InternalFormat::COMPRESSED_R11_EAC: + case InternalFormat::COMPRESSED_SIGNED_R11_EAC: + case InternalFormat::COMPRESSED_RG11_EAC: + case InternalFormat::COMPRESSED_SIGNED_RG11_EAC: return evalAlignedCompressedBlockCount<4>(value); default: @@ -370,12 +381,22 @@ namespace khronos { case InternalFormat::COMPRESSED_SRGB_S3TC_DXT1_EXT: case InternalFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case InternalFormat::COMPRESSED_RED_RGTC1: + case InternalFormat::COMPRESSED_RGB8_ETC2: + case InternalFormat::COMPRESSED_SRGB8_ETC2: + case InternalFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case InternalFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case InternalFormat::COMPRESSED_R11_EAC: + case InternalFormat::COMPRESSED_SIGNED_R11_EAC: return 8; case InternalFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM: case InternalFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: case InternalFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case InternalFormat::COMPRESSED_RG_RGTC2: + case InternalFormat::COMPRESSED_RGBA8_ETC2_EAC: + case InternalFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case InternalFormat::COMPRESSED_RG11_EAC: + case InternalFormat::COMPRESSED_SIGNED_RG11_EAC: return 16; default: From 8d25a745f0f942662bfde4894cc76374b926619d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 6 Apr 2018 17:21:49 +1200 Subject: [PATCH 059/109] Fix Controller.getActions(), .getHardware(), and .getStandard() --- libraries/controllers/src/controllers/ScriptingInterface.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/controllers/src/controllers/ScriptingInterface.h b/libraries/controllers/src/controllers/ScriptingInterface.h index 2c60ca25f5..fbc87898a4 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.h +++ b/libraries/controllers/src/controllers/ScriptingInterface.h @@ -96,9 +96,9 @@ namespace controller { Q_INVOKABLE QObject* parseMapping(const QString& json); Q_INVOKABLE QObject* loadMapping(const QString& jsonUrl); - Q_INVOKABLE const QVariantMap& getHardware() { return _hardware; } - Q_INVOKABLE const QVariantMap& getActions() { return _actions; } - Q_INVOKABLE const QVariantMap& getStandard() { return _standard; } + Q_INVOKABLE const QVariantMap getHardware() { return _hardware; } + Q_INVOKABLE const QVariantMap getActions() { return _actions; } + Q_INVOKABLE const QVariantMap getStandard() { return _standard; } Q_INVOKABLE void startInputRecording(); Q_INVOKABLE void stopInputRecording(); Q_INVOKABLE void startInputPlayback(); From 91488bbbeb1a9216fef8f8d8918d86363fb94a97 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 16 Mar 2018 22:38:39 +0300 Subject: [PATCH 060/109] align combobox to accept/cancel buttons, otherwise stretch to buttons area --- .../resources/qml/dialogs/CustomQueryDialog.qml | 15 +++++++++------ .../qml/dialogs/TabletCustomQueryDialog.qml | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/dialogs/CustomQueryDialog.qml b/interface/resources/qml/dialogs/CustomQueryDialog.qml index 6e1bb4b309..10b526b371 100644 --- a/interface/resources/qml/dialogs/CustomQueryDialog.qml +++ b/interface/resources/qml/dialogs/CustomQueryDialog.qml @@ -122,12 +122,6 @@ ModalWindow { root.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWdith) ? d.maxWidth : targetWidth); root.height = (targetHeight < d.minHeight) ? d.minHeight : ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight); - if (checkBoxField.visible && comboBoxField.visible) { - checkBoxField.width = extraInputs.width / 2; - comboBoxField.width = extraInputs.width / 2; - } else if (!checkBoxField.visible && comboBoxField.visible) { - comboBoxField.width = extraInputs.width; - } } } @@ -198,6 +192,15 @@ ModalWindow { label: root.comboBox.label; focus: Boolean(root.comboBox); visible: Boolean(root.comboBox); + Binding on x { + when: comboBoxField.visible + value: !checkBoxField.visible ? buttons.x : acceptButton.x + } + + Binding on width { + when: comboBoxField.visible + value: !checkBoxField.visible ? buttons.width : buttons.width - acceptButton.x + } anchors { right: parent.right; bottom: parent.bottom; diff --git a/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml b/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml index 7965006b8b..37c0b3612d 100644 --- a/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletCustomQueryDialog.qml @@ -140,12 +140,6 @@ TabletModalWindow { root.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWdith) ? d.maxWidth : targetWidth); modalWindowItem.height = (targetHeight < d.minHeight) ? d.minHeight : ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight); - if (checkBoxField.visible && comboBoxField.visible) { - checkBoxField.width = extraInputs.width / 2; - comboBoxField.width = extraInputs.width / 2; - } else if (!checkBoxField.visible && comboBoxField.visible) { - comboBoxField.width = extraInputs.width; - } } } @@ -223,6 +217,15 @@ TabletModalWindow { label: root.comboBox.label; focus: Boolean(root.comboBox); visible: Boolean(root.comboBox); + Binding on x { + when: comboBoxField.visible + value: !checkBoxField.visible ? buttons.x : acceptButton.x + } + + Binding on width { + when: comboBoxField.visible + value: !checkBoxField.visible ? buttons.width : buttons.width - acceptButton.x + } anchors { right: parent.right; bottom: parent.bottom; From c34a6fd00006023dbccf0585f9e3d855275fbc7d Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 16 Mar 2018 23:04:50 +0300 Subject: [PATCH 061/109] Fix styling issues - make TabletQueryDialog more consistent with TabletCustomQueryDialog --- interface/resources/qml/dialogs/TabletQueryDialog.qml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/dialogs/TabletQueryDialog.qml b/interface/resources/qml/dialogs/TabletQueryDialog.qml index 60dbc106dc..92f6864c86 100644 --- a/interface/resources/qml/dialogs/TabletQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletQueryDialog.qml @@ -89,9 +89,9 @@ TabletModalWindow { bottom: buttons.top; left: parent.left; right: parent.right; - margins: 0 + leftMargin: 12 + rightMargin: 12 bottomMargin: 2 * hifi.dimensions.contentSpacing.y - topMargin: modalWindowItem.frameMarginTop } // FIXME make a text field type that can be bound to a history for autocompletion @@ -104,8 +104,6 @@ TabletModalWindow { left: parent.left; right: parent.right; bottom: parent.bottom - leftMargin: 5 - rightMargin: 5 } } @@ -133,8 +131,8 @@ TabletModalWindow { anchors { bottom: parent.bottom right: parent.right - margins: 0 - rightMargin: hifi.dimensions.borderRadius + leftMargin: 12 + rightMargin: 12 bottomMargin: hifi.dimensions.contentSpacing.y } Button { action: cancelAction } From 3ce00acd163d661f84050cfbb7c9eee0e6302cb3 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 6 Apr 2018 00:33:42 +0300 Subject: [PATCH 062/109] rebased to the master --- interface/resources/qml/dialogs/TabletQueryDialog.qml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/dialogs/TabletQueryDialog.qml b/interface/resources/qml/dialogs/TabletQueryDialog.qml index 92f6864c86..60dbc106dc 100644 --- a/interface/resources/qml/dialogs/TabletQueryDialog.qml +++ b/interface/resources/qml/dialogs/TabletQueryDialog.qml @@ -89,9 +89,9 @@ TabletModalWindow { bottom: buttons.top; left: parent.left; right: parent.right; - leftMargin: 12 - rightMargin: 12 + margins: 0 bottomMargin: 2 * hifi.dimensions.contentSpacing.y + topMargin: modalWindowItem.frameMarginTop } // FIXME make a text field type that can be bound to a history for autocompletion @@ -104,6 +104,8 @@ TabletModalWindow { left: parent.left; right: parent.right; bottom: parent.bottom + leftMargin: 5 + rightMargin: 5 } } @@ -131,8 +133,8 @@ TabletModalWindow { anchors { bottom: parent.bottom right: parent.right - leftMargin: 12 - rightMargin: 12 + margins: 0 + rightMargin: hifi.dimensions.borderRadius bottomMargin: hifi.dimensions.contentSpacing.y } Button { action: cancelAction } From 25a44edfce2bd91241799e673376b880120ac8c8 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 6 Apr 2018 00:39:04 +0300 Subject: [PATCH 063/109] fix conditional bindings note: unfortunately there is no way to understand whether the item was anchored as even not anchored item has some anchors --- interface/resources/qml/controls-uit/TextField.qml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/controls-uit/TextField.qml b/interface/resources/qml/controls-uit/TextField.qml index 6743d08275..03b4c85a8a 100644 --- a/interface/resources/qml/controls-uit/TextField.qml +++ b/interface/resources/qml/controls-uit/TextField.qml @@ -34,6 +34,11 @@ TextField { placeholderText: textField.placeholderText + property bool rightAnchorSet: false; + anchors.onRightChanged: { + rightAnchorSet = true; + } + font.family: "Fira Sans" font.pixelSize: hifi.fontSizes.textFieldInput height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered. @@ -165,11 +170,11 @@ TextField { anchors.left: parent.left Binding on anchors.right { - when: parent.right - value: parent.right + when: rightAnchorSet + value: textField.right } Binding on wrapMode { - when: parent.right + when: rightAnchorSet value: Text.WordWrap } From 5503c7909aa75753feb26f9004f54f7e6dbc588b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 6 Apr 2018 15:18:21 -0700 Subject: [PATCH 064/109] fix materials not disappearing on deletion in certain cases --- libraries/entities/src/MaterialEntityItem.cpp | 9 ++++----- libraries/entities/src/MaterialEntityItem.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index 8b595bf69d..0f77861ba4 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -27,6 +27,10 @@ MaterialEntityItem::MaterialEntityItem(const EntityItemID& entityItemID) : Entit _type = EntityTypes::Material; } +MaterialEntityItem::~MaterialEntityItem() { + removeMaterial(); +} + EntityItemProperties MaterialEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL); @@ -328,11 +332,6 @@ void MaterialEntityItem::postParentFixup() { applyMaterial(); } -void MaterialEntityItem::preDelete() { - EntityItem::preDelete(); - removeMaterial(); -} - void MaterialEntityItem::update(const quint64& now) { if (_retryApply) { applyMaterial(); diff --git a/libraries/entities/src/MaterialEntityItem.h b/libraries/entities/src/MaterialEntityItem.h index f77077a782..e203b707cc 100644 --- a/libraries/entities/src/MaterialEntityItem.h +++ b/libraries/entities/src/MaterialEntityItem.h @@ -21,6 +21,7 @@ public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); MaterialEntityItem(const EntityItemID& entityItemID); + ~MaterialEntityItem(); ALLOW_INSTANTIATION // This class can be instantiated @@ -84,7 +85,6 @@ public: void removeMaterial(); void postParentFixup() override; - void preDelete() override; private: // URL for this material. Currently, only JSON format is supported. Set to "userData" to use the user data to live edit a material. From 6ffdae0500fd7575baa501c4d720fa6367b11196 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 6 Apr 2018 15:38:29 -0700 Subject: [PATCH 065/109] disable etc2/eac compression on 4.1 --- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 2 + .../src/gpu/gl41/GL41BackendTexture.cpp | 45 ++++++++++--------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index 3c59781f78..9479321747 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -173,6 +173,8 @@ protected: void makeProgramBindings(ShaderObject& shaderObject) override; int makeResourceBufferSlots(GLuint glprogram, const Shader::BindingSet& slotBindings,Shader::SlotSet& resourceBuffers) override; + static bool supportedTextureFormat(const gpu::Element& format); + }; } } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 09e70a3bb2..f6d3dda592 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -19,6 +19,24 @@ using namespace gpu; using namespace gpu::gl; using namespace gpu::gl41; +bool GL41Backend::supportedTextureFormat(const gpu::Element& format) { + switch (format.getSemantic()) { + case gpu::Semantic::COMPRESSED_ETC2_RGB: + case gpu::Semantic::COMPRESSED_ETC2_SRGB: + case gpu::Semantic::COMPRESSED_ETC2_RGB_PUNCHTHROUGH_ALPHA: + case gpu::Semantic::COMPRESSED_ETC2_SRGB_PUNCHTHROUGH_ALPHA: + case gpu::Semantic::COMPRESSED_ETC2_RGBA: + case gpu::Semantic::COMPRESSED_ETC2_SRGBA: + case gpu::Semantic::COMPRESSED_EAC_RED: + case gpu::Semantic::COMPRESSED_EAC_RED_SIGNED: + case gpu::Semantic::COMPRESSED_EAC_XY: + case gpu::Semantic::COMPRESSED_EAC_XY_SIGNED: + return false; + default: + return true; + } +} + GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { if (!texturePointer) { return nullptr; @@ -34,6 +52,11 @@ GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { return nullptr; } + // Check whether the texture is in a format we can deal with + if (!supportedTextureFormat(texture.getTexelFormat())) { + return nullptr; + } + GL41Texture* object = Backend::getGPUObject(texture); if (!object) { switch (texture.getUsageType()) { @@ -115,17 +138,6 @@ Size GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: - // TODO: confirm that these work on mac - case GL_COMPRESSED_RGB8_ETC2: - case GL_COMPRESSED_SRGB8_ETC2: - case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case GL_COMPRESSED_RGBA8_ETC2_EAC: - case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - case GL_COMPRESSED_R11_EAC: - case GL_COMPRESSED_SIGNED_R11_EAC: - case GL_COMPRESSED_RG11_EAC: - case GL_COMPRESSED_SIGNED_RG11_EAC: glCompressedTexSubImage2D(_target, mip, 0, yOffset, size.x, size.y, internalFormat, static_cast(sourceSize), sourcePointer); break; @@ -144,17 +156,6 @@ Size GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: - // TODO: confirm that these work on mac - case GL_COMPRESSED_RGB8_ETC2: - case GL_COMPRESSED_SRGB8_ETC2: - case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case GL_COMPRESSED_RGBA8_ETC2_EAC: - case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - case GL_COMPRESSED_R11_EAC: - case GL_COMPRESSED_SIGNED_R11_EAC: - case GL_COMPRESSED_RG11_EAC: - case GL_COMPRESSED_SIGNED_RG11_EAC: glCompressedTexSubImage2D(target, mip, 0, yOffset, size.x, size.y, internalFormat, static_cast(sourceSize), sourcePointer); break; From 6d9b69cd2e90477aebb5a4de82a44f3f4587fff2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 7 Apr 2018 16:44:58 +1200 Subject: [PATCH 066/109] Fix cloning a model overlay not cloning animation settings --- interface/src/ui/overlays/ModelOverlay.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 1c00f57eec..f8bf2c7a8d 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -35,7 +35,19 @@ ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) : _url(modelOverlay->_url), _updateModel(false), _scaleToFit(modelOverlay->_scaleToFit), - _loadPriority(modelOverlay->_loadPriority) + _loadPriority(modelOverlay->_loadPriority), + + _animationURL(modelOverlay->_animationURL), + _animationFPS(modelOverlay->_animationFPS), + _animationCurrentFrame(modelOverlay->_animationCurrentFrame), + _animationFirstFrame(modelOverlay->_animationFirstFrame), + _animationLastFrame(modelOverlay->_animationLastFrame), + _animationRunning(modelOverlay->_animationRunning), + _animationLoop(modelOverlay->_animationLoop), + _animationHold(modelOverlay->_animationHold), + _animationAllowTranslation(modelOverlay->_animationAllowTranslation) + + // Joint translations and rotations aren't copied because the model needs to load before they can be applied. { _model->setLoadingPriority(_loadPriority); if (_url.isValid()) { From 38d7b81a4f93b9e34632512c4f57568787fd6d09 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 7 Apr 2018 16:46:02 +1200 Subject: [PATCH 067/109] Add missing "get" and JSDoc for "loadPriority" property --- interface/src/ui/overlays/ModelOverlay.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index f8bf2c7a8d..4edd276bb1 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -353,6 +353,8 @@ vectorType ModelOverlay::mapJoints(mapFunction function) const { * parentID is an avatar skeleton. A value of 65535 means "no joint". * * @property {string} url - The URL of the FBX or OBJ model used for the overlay. + * @property {number} loadPriority=0.0 - The priority for loading and displaying the overlay. Overlays with higher values load + * first. * @property {Vec3} dimensions - The dimensions of the overlay. Synonym: size. * @property {Vec3} scale - The scale factor applied to the model's dimensions. * @property {object.} textures - Maps the named textures in the model to the JPG or PNG images in the urls. @@ -396,6 +398,10 @@ QVariant ModelOverlay::getProperty(const QString& property) { } } + if (property == "loadPriority") { + return _loadPriority; + } + if (property == "jointNames") { if (_model && _model->isActive()) { // note: going through Rig because Model::getJointNames() (which proxies to FBXGeometry) was always empty From ba020854b6df003016c9e55157cade2b854af99e Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 7 Apr 2018 16:46:44 +1200 Subject: [PATCH 068/109] Add missing "animationSettings.currentFrame" property JSDoc --- interface/src/ui/overlays/ModelOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 4edd276bb1..a683220819 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -369,6 +369,7 @@ vectorType ModelOverlay::mapJoints(mapFunction function) const { * @property {number} animationSettings.fps=0 - The frame rate (frames/sec) to play the animation at. * @property {number} animationSettings.firstFrame=0 - The frame to start playing at. * @property {number} animationSettings.lastFrame=0 - The frame to finish playing at. + * @property {number} animationSettings.currentFrame=0 - The current frame being played. * @property {boolean} animationSettings.running=false - Whether or not the animation is playing. * @property {boolean} animationSettings.loop=false - Whether or not the animation should repeat in a loop. * @property {boolean} animationSettings.hold=false - Whether or not when the animation finishes, the rotations and From 96178404c71e8cf9c4daae8fa05684ce81163319 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 7 Apr 2018 16:47:38 +1200 Subject: [PATCH 069/109] Document that jointTranslations and jointRotations are not cloned --- interface/src/ui/overlays/ModelOverlay.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index a683220819..e3604cf2ae 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -359,8 +359,10 @@ vectorType ModelOverlay::mapJoints(mapFunction function) const { * @property {Vec3} scale - The scale factor applied to the model's dimensions. * @property {object.} textures - Maps the named textures in the model to the JPG or PNG images in the urls. * @property {Array.} jointNames - The names of the joints - if any - in the model. Read-only - * @property {Array.} jointRotations - The relative rotations of the model's joints. - * @property {Array.} jointTranslations - The relative translations of the model's joints. + * @property {Array.} jointRotations - The relative rotations of the model's joints. Not copied if overlay is + * cloned. + * @property {Array.} jointTranslations - The relative translations of the model's joints. Not copied if overlay is + * cloned. * @property {Array.} jointOrientations - The absolute orientations of the model's joints, in world coordinates. * Read-only * @property {Array.} jointPositions - The absolute positions of the model's joints, in world coordinates. From 8093e3e5ae7c283b20acf3df6960ca6cd5f2a136 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 7 Apr 2018 16:48:05 +1200 Subject: [PATCH 070/109] Fix some miscellaneous JSDoc typos --- interface/src/ui/overlays/ModelOverlay.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index e3604cf2ae..7787766ce1 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -358,15 +358,15 @@ vectorType ModelOverlay::mapJoints(mapFunction function) const { * @property {Vec3} dimensions - The dimensions of the overlay. Synonym: size. * @property {Vec3} scale - The scale factor applied to the model's dimensions. * @property {object.} textures - Maps the named textures in the model to the JPG or PNG images in the urls. - * @property {Array.} jointNames - The names of the joints - if any - in the model. Read-only + * @property {Array.} jointNames - The names of the joints - if any - in the model. Read-only. * @property {Array.} jointRotations - The relative rotations of the model's joints. Not copied if overlay is * cloned. * @property {Array.} jointTranslations - The relative translations of the model's joints. Not copied if overlay is * cloned. * @property {Array.} jointOrientations - The absolute orientations of the model's joints, in world coordinates. - * Read-only + * Read-only. * @property {Array.} jointPositions - The absolute positions of the model's joints, in world coordinates. - * Read-only + * Read-only. * @property {string} animationSettings.url="" - The URL of an FBX file containing an animation to play. * @property {number} animationSettings.fps=0 - The frame rate (frames/sec) to play the animation at. * @property {number} animationSettings.firstFrame=0 - The frame to start playing at. From f3a745b6cb52ed819f32cc591cea25777c30c577 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 7 Apr 2018 18:53:27 +1200 Subject: [PATCH 071/109] Fix initialization order --- interface/src/ui/overlays/ModelOverlay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 7787766ce1..7edc03490c 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -40,10 +40,10 @@ ModelOverlay::ModelOverlay(const ModelOverlay* modelOverlay) : _animationURL(modelOverlay->_animationURL), _animationFPS(modelOverlay->_animationFPS), _animationCurrentFrame(modelOverlay->_animationCurrentFrame), - _animationFirstFrame(modelOverlay->_animationFirstFrame), - _animationLastFrame(modelOverlay->_animationLastFrame), _animationRunning(modelOverlay->_animationRunning), _animationLoop(modelOverlay->_animationLoop), + _animationFirstFrame(modelOverlay->_animationFirstFrame), + _animationLastFrame(modelOverlay->_animationLastFrame), _animationHold(modelOverlay->_animationHold), _animationAllowTranslation(modelOverlay->_animationAllowTranslation) From 10ce785ad746ee838169847a3753090ec30aba07 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Sat, 7 Apr 2018 09:17:08 -0700 Subject: [PATCH 072/109] If not in DEBUG then do not call qcDebug (in NetworkTexture::ktxInitialDataRequestFinished) --- .../model-networking/src/model-networking/TextureCache.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 1954f40b44..04696cea1a 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -642,8 +642,12 @@ void NetworkTexture::ktxInitialDataRequestFinished() { } if (result == ResourceRequest::Success) { + +// This is an expensive operation that we do not want in release. +#ifdef DEBUG auto extraInfo = _url == _activeUrl ? "" : QString(", %1").arg(_activeUrl.toDisplayString()); qCDebug(networking).noquote() << QString("Request finished for %1%2").arg(_url.toDisplayString(), extraInfo); +#endif _ktxHeaderData = _ktxHeaderRequest->getData(); _ktxHighMipData = _ktxMipRequest->getData(); From 7f70511d1a95ac34fd458fdedaba5636dae08b37 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Sun, 8 Apr 2018 10:32:35 -0700 Subject: [PATCH 073/109] Added a script command to clear caches. --- interface/src/scripting/TestScriptingInterface.cpp | 4 ++++ interface/src/scripting/TestScriptingInterface.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/interface/src/scripting/TestScriptingInterface.cpp b/interface/src/scripting/TestScriptingInterface.cpp index 74a15db0ce..9e7c0e142e 100644 --- a/interface/src/scripting/TestScriptingInterface.cpp +++ b/interface/src/scripting/TestScriptingInterface.cpp @@ -156,3 +156,7 @@ void TestScriptingInterface::profileRange(const QString& name, QScriptValue fn) fn.call(); } +void TestScriptingInterface::clearCaches() { + qApp->reloadResourceCaches(); +} + diff --git a/interface/src/scripting/TestScriptingInterface.h b/interface/src/scripting/TestScriptingInterface.h index aca07d110b..687cb41689 100644 --- a/interface/src/scripting/TestScriptingInterface.h +++ b/interface/src/scripting/TestScriptingInterface.h @@ -78,6 +78,11 @@ public slots: Q_INVOKABLE void profileRange(const QString& name, QScriptValue function); + /**jsdoc + * Clear all caches (menu command Reload Content) + */ + void clearCaches(); + private: bool waitForCondition(qint64 maxWaitMs, std::function condition); }; From 9b07880aabb7f6690e8989f12c7582eb66cdd6eb Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 9 Apr 2018 12:49:03 -0700 Subject: [PATCH 074/109] migrate materials from userData to materialData --- .../entities/src/EntityItemProperties.cpp | 10 + libraries/entities/src/EntityItemProperties.h | 1 + libraries/entities/src/EntityPropertyFlags.h | 1 + libraries/entities/src/EntityTree.cpp | 24 ++ libraries/entities/src/MaterialEntityItem.cpp | 25 +- libraries/entities/src/MaterialEntityItem.h | 9 +- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 3 +- scripts/system/edit.js | 11 +- scripts/system/html/css/edit-style.css | 9 +- scripts/system/html/entityProperties.html | 14 ++ scripts/system/html/js/entityProperties.js | 230 ++++++++++++++++-- 12 files changed, 296 insertions(+), 43 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index f9a96d2293..da27a4aa8c 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -363,6 +363,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_POS, materialMappingPos); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_SCALE, materialMappingScale); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_ROT, materialMappingRot); + CHECK_PROPERTY_CHANGE(PROP_MATERIAL_DATA, materialData); // Certifiable Properties CHECK_PROPERTY_CHANGE(PROP_ITEM_NAME, itemName); @@ -1376,6 +1377,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_POS, materialMappingPos); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_SCALE, materialMappingScale); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_ROT, materialMappingRot); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_DATA, materialData); } /**jsdoc @@ -1539,6 +1541,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(materialMappingPos, glmVec2, setMaterialMappingPos); COPY_PROPERTY_FROM_QSCRIPTVALUE(materialMappingScale, glmVec2, setMaterialMappingScale); COPY_PROPERTY_FROM_QSCRIPTVALUE(materialMappingRot, float, setMaterialMappingRot); + COPY_PROPERTY_FROM_QSCRIPTVALUE(materialData, QString, setMaterialData); // Certifiable Properties COPY_PROPERTY_FROM_QSCRIPTVALUE(itemName, QString, setItemName); @@ -1902,6 +1905,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_POS, MaterialMappingPos, materialMappingPos, glmVec2); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_SCALE, MaterialMappingScale, materialMappingScale, glmVec2); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_ROT, MaterialMappingRot, materialMappingRot, float); + ADD_PROPERTY_TO_MAP(PROP_MATERIAL_DATA, MaterialData, materialData, QString); // Certifiable Properties ADD_PROPERTY_TO_MAP(PROP_ITEM_NAME, ItemName, itemName, QString); @@ -2298,6 +2302,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_POS, properties.getMaterialMappingPos()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_SCALE, properties.getMaterialMappingScale()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_ROT, properties.getMaterialMappingRot()); + APPEND_ENTITY_PROPERTY(PROP_MATERIAL_DATA, properties.getMaterialData()); } APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName()); @@ -2666,6 +2671,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_POS, glmVec2, setMaterialMappingPos); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_SCALE, glmVec2, setMaterialMappingScale); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_ROT, float, setMaterialMappingRot); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_DATA, QString, setMaterialData); } READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName); @@ -2849,6 +2855,7 @@ void EntityItemProperties::markAllChanged() { _materialMappingPosChanged = true; _materialMappingScaleChanged = true; _materialMappingRotChanged = true; + _materialDataChanged = true; // Certifiable Properties _itemNameChanged = true; @@ -3200,6 +3207,9 @@ QList EntityItemProperties::listChangedProperties() { if (materialMappingRotChanged()) { out += "materialMappingRot"; } + if (materialDataChanged()) { + out += "materialData"; + } // Certifiable Properties if (itemNameChanged()) { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 0568a859ab..0d831ab786 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -230,6 +230,7 @@ public: DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_POS, MaterialMappingPos, materialMappingPos, glmVec2, glm::vec2(0, 0)); DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_SCALE, MaterialMappingScale, materialMappingScale, glmVec2, glm::vec2(1, 1)); DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_ROT, MaterialMappingRot, materialMappingRot, float, 0); + DEFINE_PROPERTY_REF(PROP_MATERIAL_DATA, MaterialData, materialData, QString, ""); // Certifiable Properties - related to Proof of Purchase certificates DEFINE_PROPERTY_REF(PROP_ITEM_NAME, ItemName, itemName, QString, ENTITY_ITEM_DEFAULT_ITEM_NAME); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 07908fe6cf..99a5f287ea 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -240,6 +240,7 @@ enum EntityPropertyList { PROP_MATERIAL_MAPPING_POS, PROP_MATERIAL_MAPPING_SCALE, PROP_MATERIAL_MAPPING_ROT, + PROP_MATERIAL_DATA, //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 7f6a7087cf..551e73abe1 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2376,6 +2376,30 @@ bool EntityTree::readFromMap(QVariantMap& map) { } } + // Convert old materials so that they use materialData instead of userData + if (contentVersion < (int)EntityVersion::MaterialData && properties.getType() == EntityTypes::EntityType::Material) { + if (properties.getMaterialURL().startsWith("userData")) { + QString materialURL = properties.getMaterialURL(); + properties.setMaterialURL(materialURL.replace("userData", "materialData")); + + QJsonObject userData = QJsonDocument::fromJson(properties.getUserData().toUtf8()).object(); + QJsonObject materialData; + QJsonValue materialVersion = userData["materialVersion"]; + if (!materialVersion.isNull()) { + materialData.insert("materialVersion", materialVersion); + userData.remove("materialVersion"); + } + QJsonValue materials = userData["materials"]; + if (!materials.isNull()) { + materialData.insert("materials", materials); + userData.remove("materials"); + } + + properties.setMaterialData(QJsonDocument(materialData).toJson()); + properties.setUserData(QJsonDocument(userData).toJson()); + } + } + EntityItemPointer entity = addEntity(entityItemID, properties); if (!entity) { qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType(); diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index 8b595bf69d..e3ed54a5d5 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -36,6 +36,7 @@ EntityItemProperties MaterialEntityItem::getProperties(EntityPropertyFlags desir COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialMappingPos, getMaterialMappingPos); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialMappingScale, getMaterialMappingScale); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialMappingRot, getMaterialMappingRot); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialData, getMaterialData); return properties; } @@ -49,6 +50,7 @@ bool MaterialEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialMappingPos, setMaterialMappingPos); SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialMappingScale, setMaterialMappingScale); SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialMappingRot, setMaterialMappingRot); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialData, setMaterialData); if (somethingChanged) { bool wantDebug = false; @@ -78,6 +80,7 @@ int MaterialEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da READ_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_POS, glm::vec2, setMaterialMappingPos); READ_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_SCALE, glm::vec2, setMaterialMappingScale); READ_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_ROT, float, setMaterialMappingRot); + READ_ENTITY_PROPERTY(PROP_MATERIAL_DATA, QString, setMaterialData); return bytesRead; } @@ -93,6 +96,7 @@ EntityPropertyFlags MaterialEntityItem::getEntityProperties(EncodeBitstreamParam requestedProperties += PROP_MATERIAL_MAPPING_POS; requestedProperties += PROP_MATERIAL_MAPPING_SCALE; requestedProperties += PROP_MATERIAL_MAPPING_ROT; + requestedProperties += PROP_MATERIAL_DATA; return requestedProperties; } @@ -112,6 +116,7 @@ void MaterialEntityItem::appendSubclassData(OctreePacketData* packetData, Encode APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_POS, getMaterialMappingPos()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_SCALE, getMaterialMappingScale()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_ROT, getMaterialMappingRot()); + APPEND_ENTITY_PROPERTY(PROP_MATERIAL_DATA, getMaterialData()); } void MaterialEntityItem::debugDump() const { @@ -145,9 +150,9 @@ std::shared_ptr MaterialEntityItem::getMaterial() const { } } -void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool userDataChanged) { - bool usingUserData = materialURLString.startsWith("userData"); - if (_materialURL != materialURLString || (usingUserData && userDataChanged)) { +void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool materialDataChanged) { + bool usingMaterialData = materialDataChanged || materialURLString.startsWith("materialData"); + if (_materialURL != materialURLString || (usingMaterialData && materialDataChanged)) { removeMaterial(); _materialURL = materialURLString; @@ -156,8 +161,8 @@ void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool u _currentMaterialName = split.last().toStdString(); } - if (usingUserData) { - _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getUserData().toUtf8()), materialURLString); + if (usingMaterialData) { + _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getMaterialData().toUtf8()), materialURLString); // Since our material changed, the current name might not be valid anymore, so we need to update setCurrentMaterialName(_currentMaterialName); @@ -191,11 +196,11 @@ void MaterialEntityItem::setCurrentMaterialName(const std::string& currentMateri } } -void MaterialEntityItem::setUserData(const QString& userData) { - if (_userData != userData) { - EntityItem::setUserData(userData); - if (_materialURL.startsWith("userData")) { - // Trigger material update when user data changes +void MaterialEntityItem::setMaterialData(const QString& materialData) { + if (_materialData != materialData) { + _materialData = materialData; + if (_materialURL.startsWith("materialData")) { + // Trigger material update when material data changes setMaterialURL(_materialURL, true); } } diff --git a/libraries/entities/src/MaterialEntityItem.h b/libraries/entities/src/MaterialEntityItem.h index f77077a782..b440738e6c 100644 --- a/libraries/entities/src/MaterialEntityItem.h +++ b/libraries/entities/src/MaterialEntityItem.h @@ -53,7 +53,7 @@ public: virtual void setUnscaledDimensions(const glm::vec3& value) override; QString getMaterialURL() const { return _materialURL; } - void setMaterialURL(const QString& materialURLString, bool userDataChanged = false); + void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false); void setCurrentMaterialName(const std::string& currentMaterialName); @@ -73,9 +73,11 @@ public: float getMaterialMappingRot() const { return _materialMappingRot; } void setMaterialMappingRot(const float& materialMappingRot); + QString getMaterialData() const { return _materialData; } + void setMaterialData(const QString& materialData); + std::shared_ptr getMaterial() const; - void setUserData(const QString& userData) override; void setParentID(const QUuid& parentID) override; void setClientOnly(bool clientOnly) override; void setOwningAvatarID(const QUuid& owningAvatarID) override; @@ -87,7 +89,7 @@ public: void preDelete() override; private: - // URL for this material. Currently, only JSON format is supported. Set to "userData" to use the user data to live edit a material. + // URL for this material. Currently, only JSON format is supported. Set to "materialData" to use the material data to live edit a material. // The following fields are supported in the JSON: // materialVersion: a uint for the version of this network material (currently, only 1 is supported) // materials, which is either an object or an array of objects, each with the following properties: @@ -117,6 +119,7 @@ private: glm::vec2 _materialMappingScale { 1, 1 }; // How much to rotate this material within its parent's UV-space (degrees) float _materialMappingRot { 0 }; + QString _materialData; NetworkMaterialResourcePointer _networkMaterial; NetworkMaterialResource::ParsedMaterials _parsedMaterials; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index a83924ee58..b49b954b99 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return static_cast(EntityVersion::ShadowControl); + return static_cast(EntityVersion::MaterialData); case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::RemovedJurisdictions); case PacketType::AvatarIdentity: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 09fd31a41e..e0d3bcdb97 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -231,7 +231,8 @@ enum class EntityVersion : PacketVersion { ZoneStageRemoved, SoftEntities, MaterialEntities, - ShadowControl + ShadowControl, + MaterialData }; enum class EntityScriptCallMethodVersion : PacketVersion { diff --git a/scripts/system/edit.js b/scripts/system/edit.js index cfaf517487..31e125213f 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -409,6 +409,12 @@ var toolBar = (function () { // default: // shapeType = "uv"; //} + var materialData = ""; + if (materialURL.startsWith("materialData")) { + materialData = JSON.stringify({ + "materials": {} + }) + } var DEFAULT_LAYERED_MATERIAL_PRIORITY = 1; if (materialURL) { @@ -416,7 +422,8 @@ var toolBar = (function () { type: "Material", materialURL: materialURL, //materialMappingMode: materialMappingMode, - priority: DEFAULT_LAYERED_MATERIAL_PRIORITY + priority: DEFAULT_LAYERED_MATERIAL_PRIORITY, + materialData: materialData }); } } @@ -2047,7 +2054,7 @@ var PropertiesTool = function (opts) { parentSelectedEntities(); } else if (data.type === 'unparent') { unparentSelectedEntities(); - } else if (data.type === 'saveUserData') { + } else if (data.type === 'saveUserData' || data.type === 'saveMaterialData') { //the event bridge and json parsing handle our avatar id string differently. var actualID = data.id.split('"')[1]; Entities.editEntity(actualID, data.properties); diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 7664ae8714..6c1931932a 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -1387,12 +1387,14 @@ input#reset-to-natural-dimensions { margin-top: 48px; } -#userdata-clear{ +#userdata-clear, +#materialdata-clear { margin-bottom: 10px; } -#static-userdata { +#static-userdata, +#static-materialData { display: none; z-index: 99; position: absolute; @@ -1403,7 +1405,8 @@ input#reset-to-natural-dimensions { background-color: #2e2e2e; } -#userdata-saved { +#userdata-saved, +#materialData-saved { margin-top:5px; font-size:16px; display:none; diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 82a450bedd..8647dca035 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -781,6 +781,20 @@ + +
+ +

+
+ + + + Saved! +
+
+
+ +
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index d2fa2eeeb0..4b6329db44 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -66,6 +66,7 @@ function enableProperties() { if (elLocked.checked === false) { removeStaticUserData(); + removeStaticMaterialData(); } } @@ -78,8 +79,13 @@ function disableProperties() { } var elLocked = document.getElementById("property-locked"); - if ($('#userdata-editor').css('display') === "block" && elLocked.checked === true) { - showStaticUserData(); + if (elLocked.checked === true) { + if ($('#userdata-editor').css('display') === "block") { + showStaticUserData(); + } + if ($('#materialdata-editor').css('display') === "block") { + showStaticMaterialData(); + } } } @@ -356,15 +362,139 @@ function userDataChanger(groupName, keyName, values, userDataElement, defaultVal multiDataUpdater(groupName, val, userDataElement, def); } +function setMaterialDataFromEditor(noUpdate) { + var json = null; + try { + json = materialEditor.get(); + } catch (e) { + alert('Invalid JSON code - look for red X in your code ', +e); + } + if (json === null) { + return; + } else { + var text = materialEditor.getText(); + if (noUpdate === true) { + EventBridge.emitWebEvent( + JSON.stringify({ + id: lastEntityID, + type: "saveMaterialData", + properties: { + materialData: text + } + }) + ); + return; + } else { + updateProperty('materialData', text); + } + } +} + function setTextareaScrolling(element) { var isScrolling = element.scrollHeight > element.offsetHeight; element.setAttribute("scrolling", isScrolling ? "true" : "false"); } +var materialEditor = null; + +function createJSONMaterialEditor() { + var container = document.getElementById("materialdata-editor"); + var options = { + search: false, + mode: 'tree', + modes: ['code', 'tree'], + name: 'materialData', + onModeChange: function() { + $('.jsoneditor-poweredBy').remove(); + }, + onError: function(e) { + alert('JSON editor:' + e); + }, + onChange: function() { + var currentJSONString = materialEditor.getText(); + + if (currentJSONString === '{"":""}') { + return; + } + $('#materialdata-save').attr('disabled', false); + + + } + }; + materialEditor = new JSONEditor(container, options); +} + +function hideNewJSONMaterialEditorButton() { + $('#materialdata-new-editor').hide(); +} + +function showSaveMaterialDataButton() { + $('#materialdata-save').show(); +} + +function hideSaveMaterialDataButton() { + $('#materialdata-save').hide(); +} + +function showNewJSONMaterialEditorButton() { + $('#materialdata-new-editor').show(); +} + +function showMaterialDataTextArea() { + $('#property-material-data').show(); +} + +function hideMaterialDataTextArea() { + $('#property-material-data').hide(); +} + +function showStaticMaterialData() { + if (materialEditor !== null) { + $('#static-materialdata').show(); + $('#static-materialdata').css('height', $('#materialdata-editor').height()); + $('#static-materialdata').text(materialEditor.getText()); + } +} + +function removeStaticMaterialData() { + $('#static-materialdata').hide(); +} + +function setMaterialEditorJSON(json) { + materialEditor.set(json); + if (materialEditor.hasOwnProperty('expandAll')) { + materialEditor.expandAll(); + } +} + +function getMaterialEditorJSON() { + return materialEditor.get(); +} + +function deleteJSONMaterialEditor() { + if (materialEditor !== null) { + materialEditor.destroy(); + materialEditor = null; + } +} + +var savedMaterialJSONTimer = null; + +function saveJSONMaterialData(noUpdate) { + setMaterialDataFromEditor(noUpdate); + $('#materialdata-saved').show(); + $('#materialdata-save').attr('disabled', true); + if (savedMaterialJSONTimer !== null) { + clearTimeout(savedMaterialJSONTimer); + } + savedMaterialJSONTimer = setTimeout(function() { + $('#materialdata-saved').hide(); + + }, EDITOR_TIMEOUT_DURATION); +} + var editor = null; -var editorTimeout = null; -var lastJSONString = null; function createJSONEditor() { var container = document.getElementById("userdata-editor"); @@ -395,11 +525,6 @@ function createJSONEditor() { function hideNewJSONEditorButton() { $('#userdata-new-editor').hide(); - -} - -function hideClearUserDataButton() { - $('#userdata-clear').hide(); } function showSaveUserDataButton() { @@ -408,17 +533,10 @@ function showSaveUserDataButton() { function hideSaveUserDataButton() { $('#userdata-save').hide(); - } function showNewJSONEditorButton() { $('#userdata-new-editor').show(); - -} - -function showClearUserDataButton() { - $('#userdata-clear').show(); - } function showUserDataTextArea() { @@ -446,7 +564,6 @@ function setEditorJSON(json) { if (editor.hasOwnProperty('expandAll')) { editor.expandAll(); } - } function getEditorJSON() { @@ -484,12 +601,15 @@ function bindAllNonJSONEditorElements() { // TODO FIXME: (JSHint) Functions declared within loops referencing // an outer scoped variable may lead to confusing semantics. field.on('focus', function(e) { - if (e.target.id === "userdata-new-editor" || e.target.id === "userdata-clear") { + if (e.target.id === "userdata-new-editor" || e.target.id === "userdata-clear" || e.target.id === "materialdata-new-editor" || e.target.id === "materialdata-clear") { return; } else { if ($('#userdata-editor').css('height') !== "0px") { saveJSONUserData(true); } + if ($('#materialdata-editor').css('height') !== "0px") { + saveJSONMaterialData(true); + } } }); } @@ -652,6 +772,10 @@ function loaded() { var elMaterialMappingScaleX = document.getElementById("property-material-mapping-scale-x"); var elMaterialMappingScaleY = document.getElementById("property-material-mapping-scale-y"); var elMaterialMappingRot = document.getElementById("property-material-mapping-rot"); + var elMaterialData = document.getElementById("property-material-data"); + var elClearMaterialData = document.getElementById("materialdata-clear"); + var elSaveMaterialData = document.getElementById("materialdata-save"); + var elNewJSONMaterialEditor = document.getElementById('materialdata-new-editor'); var elImageURL = document.getElementById("property-image-url"); @@ -772,9 +896,15 @@ function loaded() { } else if (data.type === "update") { if (!data.selections || data.selections.length === 0) { - if (editor !== null && lastEntityID !== null) { - saveJSONUserData(true); - deleteJSONEditor(); + if (lastEntityID !== null) { + if (editor !== null) { + saveJSONUserData(true); + deleteJSONEditor(); + } + if (materialEditor !== null) { + saveJSONMaterialData(true); + deleteJSONMaterialEditor(); + } } elTypeIcon.style.display = "none"; elType.innerHTML = "No selection"; @@ -783,6 +913,7 @@ function loaded() { disableProperties(); } else if (data.selections && data.selections.length > 1) { deleteJSONEditor(); + deleteJSONMaterialEditor(); var selections = data.selections; var ids = []; @@ -815,8 +946,13 @@ function loaded() { } else { properties = data.selections[0].properties; - if (lastEntityID !== '"' + properties.id + '"' && lastEntityID !== null && editor !== null) { - saveJSONUserData(true); + if (lastEntityID !== '"' + properties.id + '"' && lastEntityID !== null) { + if (editor !== null) { + saveJSONUserData(true); + } + if (materialEditor !== null) { + saveJSONMaterialData(true); + } } var doSelectElement = lastEntityID === '"' + properties.id + '"'; @@ -993,6 +1129,28 @@ function loaded() { hideNewJSONEditorButton(); } + var materialJson = null; + try { + materialJson = JSON.parse(properties.materialData); + } catch (e) { + // normal text + deleteJSONMaterialEditor(); + elMaterialData.value = properties.materialData; + showMaterialDataTextArea(); + showNewJSONMaterialEditorButton(); + hideSaveMaterialDataButton(); + } + if (materialJson !== null) { + if (materialEditor === null) { + createJSONMaterialEditor(); + } + + setMaterialEditorJSON(materialJson); + showSaveMaterialDataButton(); + hideMaterialDataTextArea(); + hideNewJSONMaterialEditorButton(); + } + elHyperlinkHref.value = properties.href; elDescription.value = properties.description; @@ -1200,6 +1358,7 @@ function loaded() { } else { enableProperties(); elSaveUserData.disabled = true; + elSaveMaterialData.disabled = true; } var activeElement = document.activeElement; @@ -1384,6 +1543,31 @@ function loaded() { showSaveUserDataButton(); }); + elClearMaterialData.addEventListener("click", function() { + deleteJSONMaterialEditor(); + elMaterialData.value = ""; + showMaterialDataTextArea(); + showNewJSONMaterialEditorButton(); + hideSaveMaterialDataButton(); + updateProperty('materialData', elMaterialData.value); + }); + + elSaveMaterialData.addEventListener("click", function() { + saveJSONMaterialData(true); + }); + + elMaterialData.addEventListener('change', createEmitTextPropertyUpdateFunction('materialData')); + + elNewJSONMaterialEditor.addEventListener('click', function() { + deleteJSONMaterialEditor(); + createJSONMaterialEditor(); + var data = {}; + setMaterialEditorJSON(data); + hideMaterialDataTextArea(); + hideNewJSONMaterialEditorButton(); + showSaveMaterialDataButton(); + }); + var colorChangeFunction = createEmitColorPropertyUpdateFunction( 'color', elColorRed, elColorGreen, elColorBlue); elColorRed.addEventListener('change', colorChangeFunction); From 8f65813924e20e25a4090db82674c0092bed36eb Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 9 Apr 2018 17:10:49 -0700 Subject: [PATCH 075/109] fix asserts on domain switch --- libraries/entities/src/EntityItem.cpp | 2 +- libraries/physics/src/PhysicalEntitySimulation.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index aab8777862..fe88f21a23 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -62,7 +62,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : EntityItem::~EntityItem() { // these pointers MUST be correct at delete, else we probably have a dangling backpointer // to this EntityItem in the corresponding data structure. - assert(!_simulated); + assert(!_simulated || (!_element && !_physicsInfo)); assert(!_element); assert(!_physicsInfo); } diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index d799577fc2..06e7069f72 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -158,7 +158,6 @@ void PhysicalEntitySimulation::clearEntitiesInternal() { EntityMotionState* motionState = static_cast(&(*stateItr)); assert(motionState); EntityItemPointer entity = motionState->getEntity(); - entity->setPhysicsInfo(nullptr); // TODO: someday when we invert the entities/physics lib dependencies we can let EntityItem delete its own PhysicsInfo // until then we must do it here delete motionState; From bba47ba2b408bcdff841d1ca90c90577621f143a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 10 Apr 2018 11:35:24 -0700 Subject: [PATCH 076/109] materials on client only entities --- .../src/RenderableMaterialEntityItem.cpp | 6 ++---- .../src/RenderableMaterialEntityItem.h | 2 -- libraries/entities/src/MaterialEntityItem.cpp | 20 ++----------------- libraries/entities/src/MaterialEntityItem.h | 2 -- 4 files changed, 4 insertions(+), 26 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index ea8edb8a08..7cea841bf0 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -18,7 +18,7 @@ bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP if (entity->getMaterial() != _drawMaterial) { return true; } - if (entity->getParentID() != _parentID || entity->getClientOnly() != _clientOnly || entity->getOwningAvatarID() != _owningAvatarID) { + if (entity->getParentID() != _parentID) { return true; } if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) { @@ -31,8 +31,6 @@ void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& withWriteLock([&] { _drawMaterial = entity->getMaterial(); _parentID = entity->getParentID(); - _clientOnly = entity->getClientOnly(); - _owningAvatarID = entity->getOwningAvatarID(); _materialMappingPos = entity->getMaterialMappingPos(); _materialMappingScale = entity->getMaterialMappingScale(); _materialMappingRot = entity->getMaterialMappingRot(); @@ -102,7 +100,7 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { graphics::MaterialPointer drawMaterial; Transform textureTransform; withReadLock([&] { - parentID = _clientOnly ? _owningAvatarID : _parentID; + parentID = _parentID; renderTransform = _renderTransform; drawMaterial = _drawMaterial; textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 8de2190a0c..96c720f79f 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -32,8 +32,6 @@ private: ShapeKey getShapeKey() override; QUuid _parentID; - bool _clientOnly; - QUuid _owningAvatarID; glm::vec2 _materialMappingPos; glm::vec2 _materialMappingScale; float _materialMappingRot; diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index 8b595bf69d..a9a5c4d934 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -249,28 +249,12 @@ void MaterialEntityItem::setParentID(const QUuid& parentID) { } } -void MaterialEntityItem::setClientOnly(bool clientOnly) { - if (getClientOnly() != clientOnly) { - removeMaterial(); - EntityItem::setClientOnly(clientOnly); - applyMaterial(); - } -} - -void MaterialEntityItem::setOwningAvatarID(const QUuid& owningAvatarID) { - if (getOwningAvatarID() != owningAvatarID) { - removeMaterial(); - EntityItem::setOwningAvatarID(owningAvatarID); - applyMaterial(); - } -} - void MaterialEntityItem::removeMaterial() { graphics::MaterialPointer material = getMaterial(); if (!material) { return; } - QUuid parentID = getClientOnly() ? getOwningAvatarID() : getParentID(); + QUuid parentID = getParentID(); if (parentID.isNull()) { return; } @@ -294,7 +278,7 @@ void MaterialEntityItem::removeMaterial() { void MaterialEntityItem::applyMaterial() { _retryApply = false; graphics::MaterialPointer material = getMaterial(); - QUuid parentID = getClientOnly() ? getOwningAvatarID() : getParentID(); + QUuid parentID = getParentID(); if (!material || parentID.isNull()) { return; } diff --git a/libraries/entities/src/MaterialEntityItem.h b/libraries/entities/src/MaterialEntityItem.h index f77077a782..11e6fc0f4d 100644 --- a/libraries/entities/src/MaterialEntityItem.h +++ b/libraries/entities/src/MaterialEntityItem.h @@ -77,8 +77,6 @@ public: void setUserData(const QString& userData) override; void setParentID(const QUuid& parentID) override; - void setClientOnly(bool clientOnly) override; - void setOwningAvatarID(const QUuid& owningAvatarID) override; void applyMaterial(); void removeMaterial(); From 9b6306601af9b9b93e73c9ec705767b48a1f288b Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 9 Apr 2018 13:21:03 -0700 Subject: [PATCH 077/109] Merge Clement's PR12700 diffs for early trace start --- interface/src/main.cpp | 13 ++++++++++++- libraries/gpu/src/gpu/Context.cpp | 1 + libraries/gpu/src/gpu/Shader.cpp | 1 + libraries/qml/src/qml/OffscreenSurface.cpp | 10 +++++++++- libraries/qml/src/qml/impl/SharedObject.cpp | 6 +++++- libraries/render-utils/src/BloomEffect.cpp | 1 + libraries/render-utils/src/HighlightEffect.cpp | 1 + libraries/render-utils/src/RenderDeferredTask.cpp | 1 + libraries/render-utils/src/RenderForwardTask.cpp | 1 + libraries/render-utils/src/RenderShadowTask.cpp | 1 + libraries/render-utils/src/RenderViewTask.cpp | 1 + libraries/render-utils/src/UpdateSceneTask.cpp | 1 + libraries/render-utils/src/ZoneRenderer.cpp | 1 + .../render/src/render/RenderFetchCullSortTask.cpp | 1 + libraries/render/src/render/ShapePipeline.cpp | 9 ++++++--- libraries/shared/src/Profile.cpp | 1 + libraries/shared/src/Profile.h | 1 + libraries/ui/src/ui/OffscreenQmlSurface.cpp | 9 +++++++++ libraries/ui/src/ui/OffscreenQmlSurfaceCache.cpp | 2 ++ 19 files changed, 56 insertions(+), 6 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 51ec4b1327..8d98766bfc 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -31,6 +31,8 @@ #include "UserActivityLogger.h" #include "MainWindow.h" +#include "Profile.h" + #ifdef Q_OS_WIN extern "C" { typedef int(__stdcall * CHECKMINSPECPROC) (); @@ -39,7 +41,10 @@ extern "C" { int main(int argc, const char* argv[]) { setupHifiApplication(BuildInfo::INTERFACE_NAME); - + auto tracer = DependencyManager::set(); + tracer->startTracing(); + PROFILE_SYNC_BEGIN(startup, "main startup", ""); + #ifdef Q_OS_LINUX QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar); #endif @@ -235,7 +240,10 @@ int main(int argc, const char* argv[]) { argvExtended.push_back("--ignore-gpu-blacklist"); int argcExtended = (int)argvExtended.size(); + PROFILE_SYNC_END(startup, "main startup", ""); + PROFILE_SYNC_BEGIN(startup, "app full ctor", ""); Application app(argcExtended, const_cast(argvExtended.data()), startupTime, runningMarkerExisted); + PROFILE_SYNC_END(startup, "app full ctor", ""); #if 0 // If we failed the OpenGLVersion check, log it. @@ -273,6 +281,9 @@ int main(int argc, const char* argv[]) { qCDebug(interfaceapp, "Created QT Application."); exitCode = app.exec(); server.close(); + + tracer->stopTracing(); + tracer->serialize(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Traces/trace-startup.json.gz"); } Application::shutdownPlugins(); diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index e1b68c88ca..dc2273ecb6 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -129,6 +129,7 @@ void Context::executeFrame(const FramePointer& frame) const { } bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings, const Shader::CompilationHandler& handler) { + PROFILE_RANGE(app, "makeProgram"); // If we're running in another DLL context, we need to fetch the program callback out of the application // FIXME find a way to do this without reliance on Qt app properties if (!_makeProgramCallback) { diff --git a/libraries/gpu/src/gpu/Shader.cpp b/libraries/gpu/src/gpu/Shader.cpp index aa7898569b..b539a84925 100755 --- a/libraries/gpu/src/gpu/Shader.cpp +++ b/libraries/gpu/src/gpu/Shader.cpp @@ -75,6 +75,7 @@ Shader::Pointer Shader::createGeometry(const Source& source) { } ShaderPointer Shader::createOrReuseProgramShader(Type type, const Pointer& vertexShader, const Pointer& geometryShader, const Pointer& pixelShader) { + PROFILE_RANGE(app, "createOrReuseProgramShader"); ProgramMapKey key(0); if (vertexShader && vertexShader->getType() == VERTEX) { diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index 9c1bb79355..2f1b3910c6 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -27,6 +27,8 @@ #include "impl/SharedObject.h" #include "impl/TextureCache.h" +#include "Profile.h" + using namespace hifi::qml; using namespace hifi::qml::impl; @@ -284,6 +286,7 @@ void OffscreenSurface::loadInternal(const QUrl& qmlSource, bool createNewContext, QQuickItem* parent, const QmlContextObjectCallback& callback) { + PROFILE_RANGE(app, "loadInternal"); if (QThread::currentThread() != thread()) { qFatal("Called load on a non-surface thread"); } @@ -304,7 +307,11 @@ void OffscreenSurface::loadInternal(const QUrl& qmlSource, } auto targetContext = contextForUrl(finalQmlSource, parent, createNewContext); - auto qmlComponent = new QQmlComponent(getSurfaceContext()->engine(), finalQmlSource, QQmlComponent::PreferSynchronous); + QQmlComponent* qmlComponent; + { + PROFILE_RANGE(app, "new QQmlComponent"); + qmlComponent = new QQmlComponent(getSurfaceContext()->engine(), finalQmlSource, QQmlComponent::PreferSynchronous); + } if (qmlComponent->isLoading()) { connect(qmlComponent, &QQmlComponent::statusChanged, this, [=](QQmlComponent::Status) { finishQmlLoad(qmlComponent, targetContext, parent, callback); }); @@ -318,6 +325,7 @@ void OffscreenSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, QQuickItem* parent, const QmlContextObjectCallback& callback) { + PROFILE_RANGE(app, "finishQmlLoad"); disconnect(qmlComponent, &QQmlComponent::statusChanged, this, 0); if (qmlComponent->isError()) { for (const auto& error : qmlComponent->errors()) { diff --git a/libraries/qml/src/qml/impl/SharedObject.cpp b/libraries/qml/src/qml/impl/SharedObject.cpp index d593169d94..b2057117f6 100644 --- a/libraries/qml/src/qml/impl/SharedObject.cpp +++ b/libraries/qml/src/qml/impl/SharedObject.cpp @@ -105,7 +105,10 @@ void SharedObject::create(OffscreenSurface* surface) { // Create a QML engine. auto qmlEngine = acquireEngine(surface); - _qmlContext = new QQmlContext(qmlEngine->rootContext(), qmlEngine); + { + PROFILE_RANGE(startup, "new QQmlContext"); + _qmlContext = new QQmlContext(qmlEngine->rootContext(), qmlEngine); + } surface->onRootContextCreated(_qmlContext); emit surface->rootContextCreated(_qmlContext); @@ -175,6 +178,7 @@ static size_t globalEngineRefCount{ 0 }; #endif QQmlEngine* SharedObject::acquireEngine(OffscreenSurface* surface) { + PROFILE_RANGE(startup, "acquireEngine"); Q_ASSERT(QThread::currentThread() == qApp->thread()); QQmlEngine* result = nullptr; diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index ddd63f012f..75ddb5f8e9 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -326,6 +326,7 @@ Bloom::Bloom() { } void Bloom::configure(const Config& config) { + PROFILE_RANGE(startup, "Bloom::build"); std::string blurName{ "BloomBlurN" }; for (auto i = 0; i < BLOOM_BLUR_LEVEL_COUNT; i++) { diff --git a/libraries/render-utils/src/HighlightEffect.cpp b/libraries/render-utils/src/HighlightEffect.cpp index d151da766b..5876b40d2b 100644 --- a/libraries/render-utils/src/HighlightEffect.cpp +++ b/libraries/render-utils/src/HighlightEffect.cpp @@ -476,6 +476,7 @@ void DrawHighlightTask::configure(const Config& config) { } void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs) { + PROFILE_RANGE(startup, "Bloom::build"); const auto items = inputs.getN(0).get(); const auto sceneFrameBuffer = inputs.getN(1); const auto primaryFramebuffer = inputs.getN(2); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 2377f5131f..6d44e7f182 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -76,6 +76,7 @@ const render::Varying RenderDeferredTask::addSelectItemJobs(JobModel& task, cons } void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { + PROFILE_RANGE(startup, "RenderDeferredTask::build"); const auto& items = input.get(); auto fadeEffect = DependencyManager::get(); diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 63370109e0..e7603d73d9 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -40,6 +40,7 @@ extern void initForwardPipelines(ShapePlumber& plumber, extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false); void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { + PROFILE_RANGE(startup, "RenderForwardTask::build"); auto items = input.get(); auto fadeEffect = DependencyManager::get(); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 69c5b3c689..84fd46f429 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -215,6 +215,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) { ::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& bounds) { + PROFILE_RANGE(startup, "RenderShadowTask::build"); return _cullFunctor(args, bounds); }; diff --git a/libraries/render-utils/src/RenderViewTask.cpp b/libraries/render-utils/src/RenderViewTask.cpp index 122fc16e61..aed2972243 100644 --- a/libraries/render-utils/src/RenderViewTask.cpp +++ b/libraries/render-utils/src/RenderViewTask.cpp @@ -17,6 +17,7 @@ void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t tagBits, uint8_t tagMask) { // auto items = input.get(); + PROFILE_RANGE(startup, "RenderViewTask::build"); // Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling // is performed, then casters not in the view frustum will be removed, which is not what we wish. task.addJob("RenderShadowTask", cullFunctor, tagBits, tagMask); diff --git a/libraries/render-utils/src/UpdateSceneTask.cpp b/libraries/render-utils/src/UpdateSceneTask.cpp index e05f28ef0d..2b4e626fed 100644 --- a/libraries/render-utils/src/UpdateSceneTask.cpp +++ b/libraries/render-utils/src/UpdateSceneTask.cpp @@ -19,6 +19,7 @@ #include "DeferredLightingEffect.h" void UpdateSceneTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { + PROFILE_RANGE(startup, "UpdateSceneTask::build"); task.addJob("LightStageSetup"); task.addJob("BackgroundStageSetup"); task.addJob("HazeStageSetup"); diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 51939efd4f..bd03668b11 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -42,6 +42,7 @@ protected: const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) { + PROFILE_RANGE(startup, "ZoneRendererTask::build"); // Filter out the sorted list of zones const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); diff --git a/libraries/render/src/render/RenderFetchCullSortTask.cpp b/libraries/render/src/render/RenderFetchCullSortTask.cpp index 7b9765dca1..629bcf81bf 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.cpp +++ b/libraries/render/src/render/RenderFetchCullSortTask.cpp @@ -20,6 +20,7 @@ using namespace render; void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varying& output, CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) { cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; + PROFILE_RANGE(startup, "RenderFetchCullSortTask::build"); // CPU jobs: // Fetch and cull the items from the scene const ItemFilter filter = ItemFilter::Builder::visibleWorldItems().withoutLayered().withTagBits(tagBits, tagMask); diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp index 92e22d86f6..35cc66315b 100644 --- a/libraries/render/src/render/ShapePipeline.cpp +++ b/libraries/render/src/render/ShapePipeline.cpp @@ -134,9 +134,12 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p locations->lightClusterFrustumBufferUnit = -1; } - auto gpuPipeline = gpu::Pipeline::create(program, state); - auto shapePipeline = std::make_shared(gpuPipeline, locations, batchSetter, itemSetter); - addPipelineHelper(filter, key, 0, shapePipeline); + { + PROFILE_RANGE(app, "Pipeline::create"); + auto gpuPipeline = gpu::Pipeline::create(program, state); + auto shapePipeline = std::make_shared(gpuPipeline, locations, batchSetter, itemSetter); + addPipelineHelper(filter, key, 0, shapePipeline); + } } const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Key& key) const { diff --git a/libraries/shared/src/Profile.cpp b/libraries/shared/src/Profile.cpp index 97def2015a..f3cbbf9262 100644 --- a/libraries/shared/src/Profile.cpp +++ b/libraries/shared/src/Profile.cpp @@ -27,6 +27,7 @@ Q_LOGGING_CATEGORY(trace_simulation_animation, "trace.simulation.animation") Q_LOGGING_CATEGORY(trace_simulation_animation_detail, "trace.simulation.animation.detail") Q_LOGGING_CATEGORY(trace_simulation_physics, "trace.simulation.physics") Q_LOGGING_CATEGORY(trace_simulation_physics_detail, "trace.simulation.physics.detail") +Q_LOGGING_CATEGORY(trace_startup, "trace.startup") Q_LOGGING_CATEGORY(trace_workload, "trace.workload") #if defined(NSIGHT_FOUND) diff --git a/libraries/shared/src/Profile.h b/libraries/shared/src/Profile.h index f2a747afa3..e78ce210c9 100644 --- a/libraries/shared/src/Profile.h +++ b/libraries/shared/src/Profile.h @@ -32,6 +32,7 @@ Q_DECLARE_LOGGING_CATEGORY(trace_simulation_animation) Q_DECLARE_LOGGING_CATEGORY(trace_simulation_animation_detail) Q_DECLARE_LOGGING_CATEGORY(trace_simulation_physics) Q_DECLARE_LOGGING_CATEGORY(trace_simulation_physics_detail) +Q_DECLARE_LOGGING_CATEGORY(trace_startup) Q_DECLARE_LOGGING_CATEGORY(trace_workload) class Duration { diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index 12e9b8b87c..cfff0405c0 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -256,6 +256,15 @@ void OffscreenQmlSurface::initializeEngine(QQmlEngine* engine) { #if !defined(Q_OS_ANDROID) rootContext->setContextProperty("FileTypeProfile", new FileTypeProfile(rootContext)); rootContext->setContextProperty("HFWebEngineProfile", new HFWebEngineProfile(rootContext)); + { + PROFILE_RANGE(startup, "FileTypeProfile"); + rootContext->setContextProperty("FileTypeProfile", new FileTypeProfile(rootContext)); + } + { + PROFILE_RANGE(startup, "HFWebEngineProfile"); + rootContext->setContextProperty("HFWebEngineProfile", new HFWebEngineProfile(rootContext)); + + } #endif rootContext->setContextProperty("Paths", DependencyManager::get().data()); rootContext->setContextProperty("Tablet", DependencyManager::get().data()); diff --git a/libraries/ui/src/ui/OffscreenQmlSurfaceCache.cpp b/libraries/ui/src/ui/OffscreenQmlSurfaceCache.cpp index 7efa36624b..51fe11fdc7 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurfaceCache.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurfaceCache.cpp @@ -12,6 +12,7 @@ #include #include "OffscreenQmlSurface.h" +#include "Profile.h" OffscreenQmlSurfaceCache::OffscreenQmlSurfaceCache() { } @@ -38,6 +39,7 @@ void OffscreenQmlSurfaceCache::reserve(const QString& rootSource, int count) { } void OffscreenQmlSurfaceCache::release(const QString& rootSource, const QSharedPointer& surface) { + PROFILE_RANGE(app, "buildSurface"); surface->pause(); _cache[rootSource].push_back(surface); } From 513a4875f0081fc7b4eafa8e82428fe3513ae851 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 9 Apr 2018 15:45:58 -0700 Subject: [PATCH 078/109] Move --traceFile option to start of main() --- interface/src/Application.cpp | 2 ++ interface/src/main.cpp | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 343074f61c..7d5a608a68 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -959,6 +959,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning())); setProperty(hifi::properties::CRASHED, _previousSessionCrashed); +#if 0 { const QString TEST_SCRIPT = "--testScript"; const QString TRACE_FILE = "--traceFile"; @@ -976,6 +977,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } } } +#endif // make sure the debug draw singleton is initialized on the main thread. DebugDraw::getInstance().removeMarker(""); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8d98766bfc..677edb0bf3 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -42,9 +42,18 @@ extern "C" { int main(int argc, const char* argv[]) { setupHifiApplication(BuildInfo::INTERFACE_NAME); auto tracer = DependencyManager::set(); - tracer->startTracing(); + const char * traceFile = ""; + { + for (int a = 1; a < argc; ++a) { + if (strcmp(argv[a], "--traceFile") == 0 && argc > a + 1) { + traceFile = argv[a + 1]; + tracer->startTracing(); + break; + } + } + } PROFILE_SYNC_BEGIN(startup, "main startup", ""); - + #ifdef Q_OS_LINUX QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar); #endif @@ -283,7 +292,7 @@ int main(int argc, const char* argv[]) { server.close(); tracer->stopTracing(); - tracer->serialize(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Traces/trace-startup.json.gz"); + tracer->serialize(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + traceFile); } Application::shutdownPlugins(); From cf3648409d5c419b20384e3dc297ab7322e23fde Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 10 Apr 2018 12:19:42 -0700 Subject: [PATCH 079/109] Allow duration for tracing, other fixes --- interface/src/Application.cpp | 7 ------- interface/src/main.cpp | 36 ++++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7d5a608a68..a0fe9ef13a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -959,10 +959,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning())); setProperty(hifi::properties::CRASHED, _previousSessionCrashed); -#if 0 { const QString TEST_SCRIPT = "--testScript"; - const QString TRACE_FILE = "--traceFile"; const QStringList args = arguments(); for (int i = 0; i < args.size() - 1; ++i) { if (args.at(i) == TEST_SCRIPT) { @@ -970,14 +968,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (QFileInfo(testScriptPath).exists()) { setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); } - } else if (args.at(i) == TRACE_FILE) { - QString traceFilePath = args.at(i + 1); - setProperty(hifi::properties::TRACING, traceFilePath); - DependencyManager::get()->startTracing(); } } } -#endif // make sure the debug draw singleton is initialized on the main thread. DebugDraw::getInstance().removeMarker(""); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 677edb0bf3..5f2afa9155 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -41,17 +41,25 @@ extern "C" { int main(int argc, const char* argv[]) { setupHifiApplication(BuildInfo::INTERFACE_NAME); + + // Early check for --traceFile argument auto tracer = DependencyManager::set(); - const char * traceFile = ""; - { - for (int a = 1; a < argc; ++a) { - if (strcmp(argv[a], "--traceFile") == 0 && argc > a + 1) { - traceFile = argv[a + 1]; - tracer->startTracing(); - break; + const char * traceFile = nullptr; + const QString traceFileFlag("--traceFile"); + float traceDuration = 0.0f; + for (int a = 1; a < argc; ++a) { + if (traceFileFlag == argv[a] && argc > a + 1) { + traceFile = argv[a + 1]; + if (argc > a + 2) { + traceDuration = atof(argv[a + 2]); } + break; } } + if (traceFile != nullptr) { + tracer->startTracing(); + } + PROFILE_SYNC_BEGIN(startup, "main startup", ""); #ifdef Q_OS_LINUX @@ -253,6 +261,14 @@ int main(int argc, const char* argv[]) { PROFILE_SYNC_BEGIN(startup, "app full ctor", ""); Application app(argcExtended, const_cast(argvExtended.data()), startupTime, runningMarkerExisted); PROFILE_SYNC_END(startup, "app full ctor", ""); + + + QTimer exitTimer; + if (traceDuration > 0.0) { + exitTimer.setSingleShot(true); + QObject::connect(&exitTimer, &QTimer::timeout, &app, &Application::quit); + exitTimer.start(int(1000 * traceDuration)); + } #if 0 // If we failed the OpenGLVersion check, log it. @@ -291,8 +307,10 @@ int main(int argc, const char* argv[]) { exitCode = app.exec(); server.close(); - tracer->stopTracing(); - tracer->serialize(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + traceFile); + if (traceFile != nullptr) { + tracer->stopTracing(); + tracer->serialize(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + traceFile); + } } Application::shutdownPlugins(); From ca5720c0158a8a3b261b32b53f7ccff9af908263 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 10 Apr 2018 13:52:46 -0700 Subject: [PATCH 080/109] Take out superfluous DependencyManager::set() --- interface/src/Application.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a0fe9ef13a..11427fb1e6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -773,7 +773,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { steamClient->init(); } - DependencyManager::set(); PROFILE_SET_THREAD_NAME("Main Thread"); #if defined(Q_OS_WIN) From 0d237f84b04b374a21b9dce6b499553010bd50b4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 Apr 2018 14:56:47 -0700 Subject: [PATCH 081/109] remove the installer information file during uninstall --- cmake/templates/NSIS.template.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index bdedf4cbba..28ac320e42 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -1234,6 +1234,9 @@ Section "Uninstall" @CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@ + ;Remove the installer information file + Delete "$INSTDIR\installer.ini" + ;Remove files we installed. ;Keep the list of directories here in sync with the File commands above. @CPACK_NSIS_DELETE_FILES@ From 7ec65e8c0ca8f850fd576db77b9e97c6251d9583 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 Apr 2018 15:02:23 -0700 Subject: [PATCH 082/109] fix unreadable baked textures in serverless tutorial --- cmake/externals/serverless-content/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/serverless-content/CMakeLists.txt b/cmake/externals/serverless-content/CMakeLists.txt index 4d0773f5f5..adfde4439a 100644 --- a/cmake/externals/serverless-content/CMakeLists.txt +++ b/cmake/externals/serverless-content/CMakeLists.txt @@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v2.zip - URL_MD5 d76bdb3e2bf7ae5d20115bd97b0c44a8 + URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v3.zip + URL_MD5 ea608c2e4c90539ab3c1d66acf0e005a CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From 8e063a600bc895be32cb9db3073183c7034cecc0 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 10 Apr 2018 20:16:36 -0700 Subject: [PATCH 083/109] Added recursive creation of MD files. --- tools/auto-tester/src/Test.cpp | 44 +++++++++++++++++++++++-- tools/auto-tester/src/Test.h | 4 ++- tools/auto-tester/src/ui/AutoTester.cpp | 10 ++++-- tools/auto-tester/src/ui/AutoTester.h | 7 ++-- tools/auto-tester/src/ui/AutoTester.ui | 27 +++++++++++---- 5 files changed, 75 insertions(+), 17 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index 5d8b9115b8..9af5f3a079 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -304,7 +304,7 @@ void Test::createRecursiveScript() { } // This method creates a `testRecursive.js` script in every sub-folder. -void Test::createRecursiveScriptsRecursively() { +void Test::createAllRecursiveScripts() { // Select folder to start recursing from QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the recursive scripts", ".", QFileDialog::ShowDirsOnly); if (topLevelDirectory == "") { @@ -559,6 +559,44 @@ void Test::createMDFile() { return; } + createMDFile(testDirectory); +} + +void Test::createAllMDFiles() { + // Select folder to start recursing from + QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the MD files", ".", QFileDialog::ShowDirsOnly); + if (topLevelDirectory == "") { + return; + } + + // First test if top-level folder has a test.js file + const QString testPathname{ topLevelDirectory + "/" + TEST_FILENAME }; + QFileInfo fileInfo(testPathname); + if (fileInfo.exists()) { + createMDFile(topLevelDirectory); + } + + QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories); + while (it.hasNext()) { + QString directory = it.next(); + + // Only process directories + QDir dir; + if (!isAValidDirectory(directory)) { + continue; + } + + const QString testPathname{ directory + "/" + TEST_FILENAME }; + QFileInfo fileInfo(testPathname); + if (fileInfo.exists()) { + createMDFile(directory); + } + } + + messageBox.information(0, "Success", "MD files have been created"); +} + +void Test::createMDFile(QString testDirectory) { // Verify folder contains test.js file QString testFileName(testDirectory + "/" + TEST_FILENAME); QFileInfo testFileInfo(testFileName); @@ -639,8 +677,8 @@ void Test::createMDFile() { int snapShotIndex { 0 }; for (size_t i = 0; i < testScriptLines.stepList.size(); ++i) { - stream << "### Step " << QString::number(i) << "\n"; - stream << "- " << testScriptLines.stepList[i + 1]->text << "\n"; + stream << "### Step " << QString::number(i + 1) << "\n"; + stream << "- " << testScriptLines.stepList[i]->text << "\n"; if (testScriptLines.stepList[i]->takeSnapshot) { stream << "- ![](./ExpectedImage_" << QString::number(snapShotIndex).rightJustified(5, '0') << ".png)\n"; ++snapShotIndex; diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index 3d04b00df9..64923da729 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -45,11 +45,13 @@ public: void finishTestsEvaluation(bool interactiveMode, QProgressBar* progressBar); void createRecursiveScript(); - void createRecursiveScriptsRecursively(); + void createAllRecursiveScripts(); void createRecursiveScript(QString topLevelDirectory, bool interactiveMode); void createTest(); void createMDFile(); + void createAllMDFiles(); + void createMDFile(QString topLevelDirectory); bool compareImageLists(bool isInteractiveMode, QProgressBar* progressBar); diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index 9153365184..fd001cc774 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -28,8 +28,8 @@ void AutoTester::on_createRecursiveScriptButton_clicked() { test->createRecursiveScript(); } -void AutoTester::on_createRecursiveScriptsRecursivelyButton_clicked() { - test->createRecursiveScriptsRecursively(); +void AutoTester::on_createAllRecursiveScriptsButton_clicked() { + test->createAllRecursiveScripts(); } void AutoTester::on_createTestButton_clicked() { @@ -37,7 +37,11 @@ void AutoTester::on_createTestButton_clicked() { } void AutoTester::on_createMDFileButton_clicked() { - test->createMDFile(); + test->createMDFile(); +} + +void AutoTester::on_createAllMDFilesButton_clicked() { + test->createAllMDFiles(); } void AutoTester::on_closeButton_clicked() { diff --git a/tools/auto-tester/src/ui/AutoTester.h b/tools/auto-tester/src/ui/AutoTester.h index 82ff3780e3..643286563c 100644 --- a/tools/auto-tester/src/ui/AutoTester.h +++ b/tools/auto-tester/src/ui/AutoTester.h @@ -28,10 +28,11 @@ public: private slots: void on_evaluateTestsButton_clicked(); void on_createRecursiveScriptButton_clicked(); - void on_createRecursiveScriptsRecursivelyButton_clicked(); + void on_createAllRecursiveScriptsButton_clicked(); void on_createTestButton_clicked(); - void on_createMDFileButton_clicked(); - void on_closeButton_clicked(); + void on_createMDFileButton_clicked(); + void on_createAllMDFilesButton_clicked(); + void on_closeButton_clicked(); void saveImage(int index); diff --git a/tools/auto-tester/src/ui/AutoTester.ui b/tools/auto-tester/src/ui/AutoTester.ui index 600de283ad..391bb61fd4 100644 --- a/tools/auto-tester/src/ui/AutoTester.ui +++ b/tools/auto-tester/src/ui/AutoTester.ui @@ -17,8 +17,8 @@ - 20 - 420 + 360 + 400 220 40 @@ -44,7 +44,7 @@ 20 - 255 + 285 220 40 @@ -70,7 +70,7 @@ 23 - 220 + 250 131 20 @@ -86,7 +86,7 @@ 20 - 310 + 340 255 23 @@ -105,14 +105,14 @@ - Create Recursive Scripts Recursively + Create all Recursive Scripts 20 - 90 + 80 220 40 @@ -121,6 +121,19 @@ Create MD file + + + + 20 + 130 + 220 + 40 + + + + Create all MD files + + From 60f4c6788faeddda9524936f98240a3b73703cfe Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Tue, 10 Apr 2018 23:04:56 -0700 Subject: [PATCH 084/109] Added creation of tests outline .MD file. --- tools/auto-tester/src/Test.cpp | 54 +++++++++++++++++++++++++ tools/auto-tester/src/Test.h | 2 + tools/auto-tester/src/ui/AutoTester.cpp | 4 ++ tools/auto-tester/src/ui/AutoTester.h | 1 + tools/auto-tester/src/ui/AutoTester.ui | 17 +++++++- 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index 9af5f3a079..b5a0069701 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -688,6 +688,60 @@ void Test::createMDFile(QString testDirectory) { mdFile.close(); } +void Test::createTestsOutline() { + QString testsRootDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the tests root folder", ".", QFileDialog::ShowDirsOnly); + if (testsRootDirectory == "") { + return; + } + + const QString testsOutlineFilename { "testsOutline.md" }; + QString mdFilename(testsRootDirectory + "/" + testsOutlineFilename); + QFile mdFile(mdFilename); + if (!mdFile.open(QIODevice::WriteOnly)) { + messageBox.critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create file " + mdFilename); + exit(-1); + } + + QTextStream stream(&mdFile); + + //Test title + stream << "# Outline of all tests\n"; + stream << "Directories with an appended (*) have an automatic test\n\n"; + + // We need to know our current depth, as this isn't given by QDirIterator + int rootDepth { testsRootDirectory.count('/') }; + + QDirIterator it(testsRootDirectory.toStdString().c_str(), QDirIterator::Subdirectories); + while (it.hasNext()) { + QString directory = it.next(); + + // Only process directories + QDir dir; + if (!isAValidDirectory(directory)) { + continue; + } + + // Ignore the utils directory + if (directory.right(5) == "utils") { + continue; + } + + int currentDepth = directory.count('/') - rootDepth; + QString prefix = QString(" ").repeated(2 * currentDepth - 1) + " - "; + stream << prefix; + stream << directory.right(directory.length() - directory.lastIndexOf("/") - 1); + QFileInfo fileInfo(directory + "/" + TEST_FILENAME); + if (fileInfo.exists()) { + stream << " (*)"; + } + stream << "\n"; + } + + mdFile.close(); + + messageBox.information(0, "Success", "Test outline file " + testsOutlineFilename + " has been created"); +} + void Test::copyJPGtoPNG(QString sourceJPGFullFilename, QString destinationPNGFullFilename) { QFile::remove(destinationPNGFullFilename); diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h index 64923da729..e69459fef2 100644 --- a/tools/auto-tester/src/Test.h +++ b/tools/auto-tester/src/Test.h @@ -53,6 +53,8 @@ public: void createAllMDFiles(); void createMDFile(QString topLevelDirectory); + void createTestsOutline(); + bool compareImageLists(bool isInteractiveMode, QProgressBar* progressBar); QStringList createListOfAll_imagesInDirectory(QString imageFormat, QString pathToImageDirectory); diff --git a/tools/auto-tester/src/ui/AutoTester.cpp b/tools/auto-tester/src/ui/AutoTester.cpp index fd001cc774..21acfe9569 100644 --- a/tools/auto-tester/src/ui/AutoTester.cpp +++ b/tools/auto-tester/src/ui/AutoTester.cpp @@ -44,6 +44,10 @@ void AutoTester::on_createAllMDFilesButton_clicked() { test->createAllMDFiles(); } +void AutoTester::on_createTestsOutlineButton_clicked() { + test->createTestsOutline(); +} + void AutoTester::on_closeButton_clicked() { exit(0); } diff --git a/tools/auto-tester/src/ui/AutoTester.h b/tools/auto-tester/src/ui/AutoTester.h index 643286563c..1788e97177 100644 --- a/tools/auto-tester/src/ui/AutoTester.h +++ b/tools/auto-tester/src/ui/AutoTester.h @@ -32,6 +32,7 @@ private slots: void on_createTestButton_clicked(); void on_createMDFileButton_clicked(); void on_createAllMDFilesButton_clicked(); + void on_createTestsOutlineButton_clicked(); void on_closeButton_clicked(); void saveImage(int index); diff --git a/tools/auto-tester/src/ui/AutoTester.ui b/tools/auto-tester/src/ui/AutoTester.ui index 391bb61fd4..2eb1314481 100644 --- a/tools/auto-tester/src/ui/AutoTester.ui +++ b/tools/auto-tester/src/ui/AutoTester.ui @@ -57,7 +57,7 @@ 360 - 75 + 35 220 40 @@ -99,7 +99,7 @@ 360 - 140 + 100 220 40 @@ -134,6 +134,19 @@ Create all MD files + + + + 20 + 180 + 220 + 40 + + + + Create Tests Outline + + From 167db14bdb88df1e8e103e92fce0b07685cbab48 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 11 Apr 2018 00:00:11 -0700 Subject: [PATCH 085/109] restoring the sampler desc layout to fix ktx cache and fixing the bug shadow when turning global shadow on off --- libraries/gpu/src/gpu/Texture.h | 3 +++ libraries/render-utils/src/DeferredLightingEffect.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 6793948d13..4d82aba595 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -128,6 +128,7 @@ public: uint8 _wrapModeV = WRAP_REPEAT; uint8 _wrapModeW = WRAP_REPEAT; + uint8 _mipOffset = 0; uint8 _minMip = 0; uint8 _maxMip = MAX_MIP_LEVEL; @@ -142,6 +143,7 @@ public: _wrapModeU == other._wrapModeU && _wrapModeV == other._wrapModeV && _wrapModeW == other._wrapModeW && + _mipOffset == other._mipOffset && _minMip == other._minMip && _maxMip == other._maxMip; } @@ -164,6 +166,7 @@ public: ComparisonFunction getComparisonFunction() const { return ComparisonFunction(_desc._comparisonFunc); } bool doComparison() const { return getComparisonFunction() != ALWAYS; } + uint8 getMipOffset() const { return _desc._mipOffset; } uint8 getMinMip() const { return _desc._minMip; } uint8 getMaxMip() const { return _desc._maxMip; } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index fc35267ddc..956b6c4a58 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -532,7 +532,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, } } - auto& program = deferredLightingEffect->_directionalSkyboxLight; + auto program = deferredLightingEffect->_directionalSkyboxLight; LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations; auto keyLight = lightAndShadow.first; From a0f3e3a0317c5e130dce24416da162569909b28b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 5 Apr 2018 12:51:59 -0700 Subject: [PATCH 086/109] add simulation ownership expiry --- .../src/entities/EntityTreeSendThread.cpp | 10 +- libraries/entities/src/EntityItem.cpp | 6 +- libraries/entities/src/EntityItem.h | 10 +- .../entities/src/EntityScriptingInterface.cpp | 1 - libraries/entities/src/EntityTree.cpp | 6 + libraries/entities/src/EntityTreeElement.h | 4 - .../entities/src/SimpleEntitySimulation.cpp | 105 +++++++++++------- .../entities/src/SimpleEntitySimulation.h | 18 +-- .../octree/src/DirtyOctreeElementOperator.cpp | 1 + libraries/octree/src/OctreeElement.h | 4 + libraries/physics/src/EntityMotionState.cpp | 8 +- 11 files changed, 105 insertions(+), 68 deletions(-) diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index 94d21f1c9a..4aa52922c0 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -311,7 +311,8 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree _sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY)); _entitiesInQueue.insert(entity.get()); } - } else if (entity->getLastEdited() > knownTimestamp->second) { + } else if (entity->getLastEdited() > knownTimestamp->second + || entity->getLastChangedOnServer() > knownTimestamp->second) { // it is known and it changed --> put it on the queue with any priority // TODO: sort these correctly _sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY)); @@ -330,7 +331,9 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree return; } auto knownTimestamp = _knownState.find(entity.get()); - if (knownTimestamp == _knownState.end() || entity->getLastEdited() > knownTimestamp->second) { + if (knownTimestamp == _knownState.end() + || entity->getLastEdited() > knownTimestamp->second + || entity->getLastChangedOnServer() > knownTimestamp->second) { _sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY)); _entitiesInQueue.insert(entity.get()); } @@ -382,7 +385,8 @@ void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTree _sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY)); _entitiesInQueue.insert(entity.get()); } - } else if (entity->getLastEdited() > knownTimestamp->second) { + } else if (entity->getLastEdited() > knownTimestamp->second + || entity->getLastChangedOnServer() > knownTimestamp->second) { // it is known and it changed --> put it on the queue with any priority // TODO: sort these correctly _sendQueue.push(PrioritizedEntity(entity, PrioritizedEntity::WHEN_IN_DOUBT_PRIORITY)); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index aab8777862..84064a8b7b 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -693,7 +693,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // the entity-server is awarding us ownership which is what we want _simulationOwner.set(newSimOwner); } - } else if (newSimOwner.matchesValidID(myNodeID) && !_hasBidOnSimulation) { + } else if (newSimOwner.matchesValidID(myNodeID) && !_simulationOwner.pendingTake(now)) { // entity-server tells us that we have simulation ownership while we never requested this for this EntityItem, // this could happen when the user reloads the cache and entity tree. markDirtyFlags(Simulation::DIRTY_SIMULATOR_ID); @@ -1946,10 +1946,6 @@ void EntityItem::setPendingOwnershipPriority(uint8_t priority, const quint64& ti _simulationOwner.setPendingPriority(priority, timestamp); } -void EntityItem::rememberHasSimulationOwnershipBid() const { - _hasBidOnSimulation = true; -} - QString EntityItem::actionsToDebugString() { QString result; QVector serializedActions; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index ebbeaaa254..de98c1a47a 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -58,6 +58,9 @@ using EntityTreeElementExtraEncodeDataPointer = std::shared_ptr getMaterials(); + void setSimulationOwnershipExpiry(uint64_t expiry) { _simulationOwnershipExpiry = expiry; } + uint64_t getSimulationOwnershipExpiry() const { return _simulationOwnershipExpiry; } + signals: void requestRenderUpdate(); @@ -619,9 +625,6 @@ protected: static quint64 _rememberDeletedActionTime; mutable QHash _previouslyDeletedActions; - // per entity keep state if it ever bid on simulation, so that we can ignore false simulation ownership - mutable bool _hasBidOnSimulation { false }; - QUuid _sourceUUID; /// the server node UUID we came from bool _clientOnly { false }; @@ -642,6 +645,7 @@ protected: quint64 _lastUpdatedAngularVelocityTimestamp { 0 }; quint64 _lastUpdatedAccelerationTimestamp { 0 }; quint64 _lastUpdatedQueryAACubeTimestamp { 0 }; + uint64_t _simulationOwnershipExpiry { 0 }; bool _cauterized { false }; // if true, don't draw because it would obscure 1st-person camera diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 2e9b386ba5..135bbf63ac 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -454,7 +454,6 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& // we make a bid for simulation ownership properties.setSimulationOwner(myNodeID, SCRIPT_POKE_SIMULATION_PRIORITY); entity->flagForOwnershipBid(SCRIPT_POKE_SIMULATION_PRIORITY); - entity->rememberHasSimulationOwnershipBid(); } } if (properties.queryAACubeRelatedPropertyChanged()) { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 7f6a7087cf..81fb2d7d37 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -370,12 +370,18 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti simulationBlocked = false; } } + if (!simulationBlocked) { + entity->setSimulationOwnershipExpiry(usecTimestampNow() + MAX_INCOMING_SIMULATION_UPDATE_PERIOD); + } } else { // the entire update is suspect --> ignore it return false; } } else if (simulationBlocked) { simulationBlocked = senderID != entity->getSimulatorID(); + if (!simulationBlocked) { + entity->setSimulationOwnershipExpiry(usecTimestampNow() + MAX_INCOMING_SIMULATION_UPDATE_PERIOD); + } } if (simulationBlocked) { // squash ownership and physics-related changes. diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index b219d64d9d..a56af5d03f 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -243,14 +243,10 @@ public: return std::static_pointer_cast(shared_from_this()); } - void bumpChangedContent() { _lastChangedContent = usecTimestampNow(); } - uint64_t getLastChangedContent() const { return _lastChangedContent; } - protected: virtual void init(unsigned char * octalCode) override; EntityTreePointer _myTree; EntityItems _entityItems; - uint64_t _lastChangedContent { 0 }; }; #endif // hifi_EntityTreeElement_h diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index a2aba0169d..66f9b4111b 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -9,8 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -//#include - #include "SimpleEntitySimulation.h" #include @@ -27,16 +25,13 @@ void SimpleEntitySimulation::clearOwnership(const QUuid& ownerID) { EntityItemPointer entity = *itemItr; if (entity->getSimulatorID() == ownerID) { // the simulator has abandonded this object --> remove from owned list - qCDebug(entities) << "auto-removing simulation owner " << entity->getSimulatorID(); itemItr = _entitiesWithSimulationOwner.erase(itemItr); if (entity->getDynamic() && entity->hasLocalVelocity()) { // it is still moving dynamically --> add to orphaned list _entitiesThatNeedSimulationOwner.insert(entity); uint64_t expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; - if (expiry < _nextOwnerlessExpiry) { - _nextOwnerlessExpiry = expiry; - } + _nextOwnerlessExpiry = glm::min(_nextOwnerlessExpiry, expiry); } // remove ownership and dirty all the tree elements that contain the it @@ -51,37 +46,8 @@ void SimpleEntitySimulation::clearOwnership(const QUuid& ownerID) { } void SimpleEntitySimulation::updateEntitiesInternal(uint64_t now) { - if (now > _nextOwnerlessExpiry) { - // search for ownerless objects that have expired - QMutexLocker lock(&_mutex); - _nextOwnerlessExpiry = std::numeric_limits::max(); - SetOfEntities::iterator itemItr = _entitiesThatNeedSimulationOwner.begin(); - while (itemItr != _entitiesThatNeedSimulationOwner.end()) { - EntityItemPointer entity = *itemItr; - uint64_t expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; - if (expiry < now) { - // no simulators have volunteered ownership --> remove from list - itemItr = _entitiesThatNeedSimulationOwner.erase(itemItr); - - if (entity->getSimulatorID().isNull() && entity->getDynamic() && entity->hasLocalVelocity()) { - // zero the derivatives - entity->setVelocity(Vectors::ZERO); - entity->setAngularVelocity(Vectors::ZERO); - entity->setAcceleration(Vectors::ZERO); - - // dirty all the tree elements that contain it - entity->markAsChangedOnServer(); - DirtyOctreeElementOperator op(entity->getElement()); - getEntityTree()->recurseTreeWithOperator(&op); - } - } else { - ++itemItr; - if (expiry < _nextOwnerlessExpiry) { - _nextOwnerlessExpiry = expiry; - } - } - } - } + expireStaleOwnerships(now); + stopOwnerlessEntities(now); } void SimpleEntitySimulation::addEntityInternal(EntityItemPointer entity) { @@ -93,13 +59,12 @@ void SimpleEntitySimulation::addEntityInternal(EntityItemPointer entity) { if (!entity->getSimulatorID().isNull()) { QMutexLocker lock(&_mutex); _entitiesWithSimulationOwner.insert(entity); + _nextStaleOwnershipExpiry = glm::min(_nextStaleOwnershipExpiry, entity->getSimulationOwnershipExpiry()); } else if (entity->getDynamic() && entity->hasLocalVelocity()) { QMutexLocker lock(&_mutex); _entitiesThatNeedSimulationOwner.insert(entity); uint64_t expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; - if (expiry < _nextOwnerlessExpiry) { - _nextOwnerlessExpiry = expiry; - } + _nextOwnerlessExpiry = glm::min(_nextOwnerlessExpiry, expiry); } } @@ -128,13 +93,12 @@ void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) { if (entity->getDynamic() && entity->hasLocalVelocity()) { _entitiesThatNeedSimulationOwner.insert(entity); uint64_t expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; - if (expiry < _nextOwnerlessExpiry) { - _nextOwnerlessExpiry = expiry; - } + _nextOwnerlessExpiry = glm::min(_nextOwnerlessExpiry, expiry); } } else { QMutexLocker lock(&_mutex); _entitiesWithSimulationOwner.insert(entity); + _nextStaleOwnershipExpiry = glm::min(_nextStaleOwnershipExpiry, entity->getSimulationOwnershipExpiry()); _entitiesThatNeedSimulationOwner.remove(entity); } entity->clearDirtyFlags(); @@ -155,3 +119,58 @@ void SimpleEntitySimulation::sortEntitiesThatMoved() { } EntitySimulation::sortEntitiesThatMoved(); } + +void SimpleEntitySimulation::expireStaleOwnerships(uint64_t now) { + if (now > _nextStaleOwnershipExpiry) { + _nextStaleOwnershipExpiry = (uint64_t)(-1); + SetOfEntities::iterator itemItr = _entitiesWithSimulationOwner.begin(); + while (itemItr != _entitiesWithSimulationOwner.end()) { + EntityItemPointer entity = *itemItr; + uint64_t expiry = entity->getSimulationOwnershipExpiry(); + if (now > expiry) { + itemItr = _entitiesWithSimulationOwner.erase(itemItr); + + // remove ownership and dirty all the tree elements that contain the it + entity->clearSimulationOwnership(); + entity->markAsChangedOnServer(); + DirtyOctreeElementOperator op(entity->getElement()); + getEntityTree()->recurseTreeWithOperator(&op); + } else { + _nextStaleOwnershipExpiry = glm::min(_nextStaleOwnershipExpiry, expiry); + ++itemItr; + } + } + } +} + +void SimpleEntitySimulation::stopOwnerlessEntities(uint64_t now) { + if (now > _nextOwnerlessExpiry) { + // search for ownerless objects that have expired + QMutexLocker lock(&_mutex); + _nextOwnerlessExpiry = (uint64_t)(-1); + SetOfEntities::iterator itemItr = _entitiesThatNeedSimulationOwner.begin(); + while (itemItr != _entitiesThatNeedSimulationOwner.end()) { + EntityItemPointer entity = *itemItr; + uint64_t expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; + if (expiry < now) { + // no simulators have volunteered ownership --> remove from list + itemItr = _entitiesThatNeedSimulationOwner.erase(itemItr); + + if (entity->getSimulatorID().isNull() && entity->getDynamic() && entity->hasLocalVelocity()) { + // zero the derivatives + entity->setVelocity(Vectors::ZERO); + entity->setAngularVelocity(Vectors::ZERO); + entity->setAcceleration(Vectors::ZERO); + + // dirty all the tree elements that contain it + entity->markAsChangedOnServer(); + DirtyOctreeElementOperator op(entity->getElement()); + getEntityTree()->recurseTreeWithOperator(&op); + } + } else { + _nextOwnerlessExpiry = glm::min(_nextOwnerlessExpiry, expiry); + ++itemItr; + } + } + } +} diff --git a/libraries/entities/src/SimpleEntitySimulation.h b/libraries/entities/src/SimpleEntitySimulation.h index 95c996a920..8ac9b69e93 100644 --- a/libraries/entities/src/SimpleEntitySimulation.h +++ b/libraries/entities/src/SimpleEntitySimulation.h @@ -23,22 +23,26 @@ using SimpleEntitySimulationPointer = std::shared_ptr; class SimpleEntitySimulation : public EntitySimulation { public: SimpleEntitySimulation() : EntitySimulation() { } - virtual ~SimpleEntitySimulation() { clearEntitiesInternal(); } + ~SimpleEntitySimulation() { clearEntitiesInternal(); } void clearOwnership(const QUuid& ownerID); protected: - virtual void updateEntitiesInternal(uint64_t now) override; - virtual void addEntityInternal(EntityItemPointer entity) override; - virtual void removeEntityInternal(EntityItemPointer entity) override; - virtual void changeEntityInternal(EntityItemPointer entity) override; - virtual void clearEntitiesInternal() override; + void updateEntitiesInternal(uint64_t now) override; + void addEntityInternal(EntityItemPointer entity) override; + void removeEntityInternal(EntityItemPointer entity) override; + void changeEntityInternal(EntityItemPointer entity) override; + void clearEntitiesInternal() override; - virtual void sortEntitiesThatMoved() override; + void sortEntitiesThatMoved() override; + + void expireStaleOwnerships(uint64_t now); + void stopOwnerlessEntities(uint64_t now); SetOfEntities _entitiesWithSimulationOwner; SetOfEntities _entitiesThatNeedSimulationOwner; uint64_t _nextOwnerlessExpiry { 0 }; + uint64_t _nextStaleOwnershipExpiry { (uint64_t)(-1) }; }; #endif // hifi_SimpleEntitySimulation_h diff --git a/libraries/octree/src/DirtyOctreeElementOperator.cpp b/libraries/octree/src/DirtyOctreeElementOperator.cpp index ed8d26cf72..ae01a3d608 100644 --- a/libraries/octree/src/DirtyOctreeElementOperator.cpp +++ b/libraries/octree/src/DirtyOctreeElementOperator.cpp @@ -14,6 +14,7 @@ DirtyOctreeElementOperator::DirtyOctreeElementOperator(const OctreeElementPointer& element) : _element(element) { assert(_element.get()); + _element->bumpChangedContent(); _point = _element->getAACube().calcCenter(); } diff --git a/libraries/octree/src/OctreeElement.h b/libraries/octree/src/OctreeElement.h index 9ab5d9429d..514039713b 100644 --- a/libraries/octree/src/OctreeElement.h +++ b/libraries/octree/src/OctreeElement.h @@ -219,6 +219,9 @@ public: int getMyChildContaining(const AABox& box) const; int getMyChildContainingPoint(const glm::vec3& point) const; + void bumpChangedContent() { _lastChangedContent = usecTimestampNow(); } + uint64_t getLastChangedContent() const { return _lastChangedContent; } + protected: void deleteAllChildren(); @@ -235,6 +238,7 @@ protected: } _octalCode; quint64 _lastChanged; /// Client and server, timestamp this node was last changed, 8 bytes + uint64_t _lastChangedContent { 0 }; /// Client and server, pointers to child nodes, various encodings #ifdef SIMPLE_CHILD_ARRAY diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 6a25700ce8..c2bacd4949 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -365,6 +365,11 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { return true; } + if (usecTimestampNow() > _entity->getSimulationOwnershipExpiry()) { + // send update every so often else server will revoke our ownership + return true; + } + _lastStep = simulationStep; if (glm::length2(_serverVelocity) > 0.0f) { // the entity-server doesn't know where avatars are, so it doesn't do simple extrapolation for children of @@ -525,8 +530,6 @@ void EntityMotionState::sendBid(OctreeEditPacketSender* packetSender, uint32_t s properties.setSimulationOwner(Physics::getSessionUUID(), bidPriority); // copy _bidPriority into pendingPriority... _entity->setPendingOwnershipPriority(_bidPriority, now); - // don't forget to remember that we have made a bid - _entity->rememberHasSimulationOwnershipBid(); EntityTreeElementPointer element = _entity->getElement(); EntityTreePointer tree = element ? element->getTree() : nullptr; @@ -585,6 +588,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ // set the LastEdited of the properties but NOT the entity itself quint64 now = usecTimestampNow(); properties.setLastEdited(now); + _entity->setSimulationOwnershipExpiry(now + MAX_OUTGOING_SIMULATION_UPDATE_PERIOD); if (_numInactiveUpdates > 0) { // the entity is stopped and inactive so we tell the server we're clearing simulatorID From 48ddfb09c2db03b3ad13eb1ab292185863eb7e24 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 11 Apr 2018 10:08:33 -0700 Subject: [PATCH 087/109] Support per-avatar gain adjustment on stereo input streams --- assignment-client/src/audio/AudioMixerSlave.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index ccdd2fca4f..f95d51720f 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -322,6 +322,11 @@ void AudioMixerSlave::addStream(AudioMixerClientData& listenerNodeData, const QU // stereo sources are not passed through HRTF if (streamToAdd.isStereo()) { + + // apply the avatar gain adjustment + auto& hrtf = listenerNodeData.hrtfForStream(sourceNodeID, streamToAdd.getStreamIdentifier()); + gain *= hrtf.getGainAdjustment(); + for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; ++i) { _mixSamples[i] += float(streamPopOutput[i] * gain / AudioConstants::MAX_SAMPLE_VALUE); } From 67ec766af2a5161c9ffd9ec7af8291cf84342b98 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 11 Apr 2018 10:24:01 -0700 Subject: [PATCH 088/109] saving work. --- libraries/image/src/image/Image.cpp | 2 +- tools/bake-tools/bake.py | 16 ++++++++++++---- tools/bake-tools/convertToRelativePaths.py | 9 +++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index 696e311495..0b4acb29c4 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -37,7 +37,7 @@ bool DEV_DECIMATE_TEXTURES = false; std::atomic DECIMATED_TEXTURE_COUNT{ 0 }; std::atomic RECTIFIED_TEXTURE_COUNT{ 0 }; -static const auto HDR_FORMAT = gpu::Element::COLOR_R11G11B10; +static const auto& HDR_FORMAT = gpu::Element::COLOR_R11G11B10; static std::atomic compressColorTextures { false }; static std::atomic compressNormalTextures { false }; diff --git a/tools/bake-tools/bake.py b/tools/bake-tools/bake.py index cad638c911..4051b7a7ca 100644 --- a/tools/bake-tools/bake.py +++ b/tools/bake-tools/bake.py @@ -44,26 +44,34 @@ def groupKTXFiles(directory, filePath): originalFilePath.strip() shutil.move(originalFilePath, newFilePath) -def bakeFile(filePath, outputDirectory): +def bakeFile(filePath, outputDirectory, fileType): createDirectory(outputDirectory) - cmd = EXE + ' -i ' + filePath + ' -o ' + outputDirectory + ' -t fbx' + cmd = EXE + ' -i ' + filePath + ' -o ' + outputDirectory + ' -t ' + fileType args = shlex.split(cmd) process = subprocess.Popen(cmd, stdout=False, stderr=False) process.wait() bakedFile = os.path.splitext(filePath)[0] - groupKTXFiles(outputDirectory, bakedFile) + if fileType == 'fbx': + groupKTXFiles(outputDirectory, bakedFile) def bakeFilesInDirectory(directory, outputDirectory): rootDirectory = os.path.basename(os.path.normpath(directory)) for root, subFolders, filenames in os.walk(directory): for filename in filenames: appendPath = getRelativePath(directory, root, rootDirectory); + name, ext = os.path.splitext('file.txt') if filename.endswith('.fbx'): filePath = os.sep.join([root, filename]) absFilePath = os.path.abspath(filePath) outputFolder = os.path.join(outputDirectory, appendPath) print "Baking file: " + filename - bakeFile(absFilePath, outputFolder) + bakeFile(absFilePath, outputFolder, 'fbx') + elif os.path.basename(root) == 'skyboxes': + filePath = os.sep.join([root, filename]) + absFilePath = os.path.abspath(filePath) + outputFolder = os.path.join(outputDirectory, appendPath) + print "Baking file: " + filename + bakeFile(absFilePath, outputFolder, 'png') else: filePath = os.sep.join([root, filename]) absFilePath = os.path.abspath(filePath) diff --git a/tools/bake-tools/convertToRelativePaths.py b/tools/bake-tools/convertToRelativePaths.py index 27a7b7ac02..2798e2849f 100644 --- a/tools/bake-tools/convertToRelativePaths.py +++ b/tools/bake-tools/convertToRelativePaths.py @@ -65,6 +65,15 @@ def main(): except: value = handleURL(value) + + if prop == "ambientLight": + for index in value: + value[index] = handleURL(value[index]) + + if prop == "skybox": + for index in value: + value[index] = handleURL(value[index]) + if prop == "serverScripts": value = handleURL(value) From 537e54e9d461f06c4601eeb97e68bb9120bcd935 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 11 Apr 2018 10:54:31 -0700 Subject: [PATCH 089/109] Optimize the mixing loops --- assignment-client/src/audio/AudioMixerSlave.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index f95d51720f..e0c7e71589 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -327,8 +327,9 @@ void AudioMixerSlave::addStream(AudioMixerClientData& listenerNodeData, const QU auto& hrtf = listenerNodeData.hrtfForStream(sourceNodeID, streamToAdd.getStreamIdentifier()); gain *= hrtf.getGainAdjustment(); - for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; ++i) { - _mixSamples[i] += float(streamPopOutput[i] * gain / AudioConstants::MAX_SAMPLE_VALUE); + for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; i++) { + _mixSamples[2*i+0] += (float)streamPopOutput[2*i+0] * gain * (1/32768.0f); + _mixSamples[2*i+1] += (float)streamPopOutput[2*i+1] * gain * (1/32768.0f); } ++stats.manualStereoMixes; @@ -337,10 +338,10 @@ void AudioMixerSlave::addStream(AudioMixerClientData& listenerNodeData, const QU // echo sources are not passed through HRTF if (isEcho) { - for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_STEREO; i += 2) { - auto monoSample = float(streamPopOutput[i / 2] * gain / AudioConstants::MAX_SAMPLE_VALUE); - _mixSamples[i] += monoSample; - _mixSamples[i + 1] += monoSample; + for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; i++) { + float sample = (float)streamPopOutput[i] * gain * (1/32768.0f); + _mixSamples[2*i+0] += sample; + _mixSamples[2*i+1] += sample; } ++stats.manualEchoMixes; From 366498c6d30ef6149576374a13238568c6f738c1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 11 Apr 2018 11:44:49 -0700 Subject: [PATCH 090/109] switch to backtrace's newer crashpad blob --- cmake/externals/crashpad/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/crashpad/CMakeLists.txt b/cmake/externals/crashpad/CMakeLists.txt index c464dcbc1b..82e4c45841 100644 --- a/cmake/externals/crashpad/CMakeLists.txt +++ b/cmake/externals/crashpad/CMakeLists.txt @@ -6,8 +6,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://backtrace.io/download/crashpad_062317.zip - URL_MD5 65817e564b3628492abfc1dbd2a1e98b + URL http://public.highfidelity.com/dependencies/crashpad_062317.zip + URL_MD5 9c84b77f5f23daf939da1371825ed2b1 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From 625905007fc2224908d308e19d67480cd77fce71 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 11 Apr 2018 11:49:53 -0700 Subject: [PATCH 091/109] use new filename for new blob --- cmake/externals/crashpad/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/externals/crashpad/CMakeLists.txt b/cmake/externals/crashpad/CMakeLists.txt index 82e4c45841..e509e115e4 100644 --- a/cmake/externals/crashpad/CMakeLists.txt +++ b/cmake/externals/crashpad/CMakeLists.txt @@ -6,7 +6,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://public.highfidelity.com/dependencies/crashpad_062317.zip + URL http://public.highfidelity.com/dependencies/crashpad_062317.1.zip URL_MD5 9c84b77f5f23daf939da1371825ed2b1 CONFIGURE_COMMAND "" BUILD_COMMAND "" From 16f6ac529536e07c524614e9ecc7325c80bcf13f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 11 Apr 2018 13:36:49 -0700 Subject: [PATCH 092/109] use serverless content with baked skybox and help textures --- cmake/externals/serverless-content/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/serverless-content/CMakeLists.txt b/cmake/externals/serverless-content/CMakeLists.txt index adfde4439a..a08b589ec2 100644 --- a/cmake/externals/serverless-content/CMakeLists.txt +++ b/cmake/externals/serverless-content/CMakeLists.txt @@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v3.zip - URL_MD5 ea608c2e4c90539ab3c1d66acf0e005a + URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v4.zip + URL_MD5 d4f42f630986c83427ff39e1fe9908c6 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From b82f2510f2addbde1ddf636fe3a4e2df8bb0d674 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 12 Apr 2018 08:55:47 +1200 Subject: [PATCH 093/109] Fix location.protocol value for serverless domains --- libraries/networking/src/AddressManager.cpp | 4 ++++ libraries/networking/src/AddressManager.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 3c24cc796c..52253b1cbc 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -39,6 +39,10 @@ bool AddressManager::isConnected() { return DependencyManager::get()->getDomainHandler().isConnected(); } +QString AddressManager::getProtocol() const { + return _domainURL.scheme(); +} + QUrl AddressManager::currentAddress(bool domainOnly) const { QUrl hifiURL = _domainURL; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index b42aec2771..b6a18b117d 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -145,7 +145,7 @@ public: }; bool isConnected(); - const QString& getProtocol() { return URL_SCHEME_HIFI; }; + QString getProtocol() const; QUrl currentAddress(bool domainOnly = false) const; QUrl currentFacingAddress() const; From 3270409b7b2ee76f846d2eb1f2cab70f25466c28 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 11 Apr 2018 14:06:30 -0700 Subject: [PATCH 094/109] possible fix for missing alpha on server restart --- libraries/entities/src/EntityItemProperties.cpp | 2 +- libraries/entities/src/ShapeEntityItem.cpp | 4 +++- libraries/entities/src/ShapeEntityItem.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index f9a96d2293..859a8db2f4 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1208,6 +1208,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACTION_DATA, actionData); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCKED, locked); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_USER_DATA, userData); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha); // Certifiable Properties COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ITEM_NAME, itemName); @@ -1252,7 +1253,6 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_SPREAD, colorSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_START, colorStart); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_FINISH, colorFinish); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_SPREAD, alphaSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_START, alphaStart); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_FINISH, alphaFinish); diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 60ba429938..99f18d2dac 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -117,8 +117,10 @@ ShapeEntityItem::ShapeEntityItem(const EntityItemID& entityItemID) : EntityItem( EntityItemProperties ShapeEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class - properties.setColor(getXColor()); properties.setShape(entity::stringFromShape(getShape())); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha); + return properties; } diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index 97202afcf7..adc33b764b 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -105,7 +105,7 @@ public: protected: - float _alpha { 1 }; // FIXME: This property is not used. + float _alpha { 1.0f }; rgbColor _color; entity::Shape _shape { entity::Shape::Sphere }; From cdc248129c9c7d9cdcd862a725bdf5713052b687 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 11 Apr 2018 14:25:06 -0700 Subject: [PATCH 095/109] fix grab.js --- scripts/system/controllers/grab.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index 1171703847..776fd11e5c 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -8,7 +8,7 @@ // // Grab's physically moveable entities with the mouse, by applying a spring force. // -// Updated November 22, 2016 by Philip Rosedale: Add distance attenuation of grab effect +// Updated November 22, 2016 by Philip Rosedale: Add distance attenuation of grab effect // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -444,6 +444,7 @@ Grabber.prototype.releaseEvent = function(event) { this.actionID = null; Pointers.setRenderState(this.mouseRayEntities, ""); + Pointers.setLockEndUUID(this.mouseRayEntities, null, false); var args = "mouse"; Entities.callEntityMethod(this.entityID, "releaseGrab", args); From c458b587ac9d45554d9b6cceddf86c2b4d6b5ece Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Wed, 11 Apr 2018 16:50:27 -0700 Subject: [PATCH 096/109] Completed creation of testsOutline.md. --- tools/auto-tester/src/Test.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index b5a0069701..99f9025fdd 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -711,6 +711,7 @@ void Test::createTestsOutline() { // We need to know our current depth, as this isn't given by QDirIterator int rootDepth { testsRootDirectory.count('/') }; + // Each test is shown as the folder name linking to the matching GitHub URL, and the path to the associated test.md file QDirIterator it(testsRootDirectory.toStdString().c_str(), QDirIterator::Subdirectories); while (it.hasNext()) { QString directory = it.next(); @@ -726,12 +727,28 @@ void Test::createTestsOutline() { continue; } + // The prefix is the MarkDown prefix needed for correct indentation + // It consists of 2 spaces for each level of indentation, folled by a dash sign int currentDepth = directory.count('/') - rootDepth; QString prefix = QString(" ").repeated(2 * currentDepth - 1) + " - "; - stream << prefix; - stream << directory.right(directory.length() - directory.lastIndexOf("/") - 1); - QFileInfo fileInfo(directory + "/" + TEST_FILENAME); - if (fileInfo.exists()) { + + // The directory name appears after the last slash (we are assured there is at least 1). + QString directoryName = directory.right(directory.length() - directory.lastIndexOf("/") - 1); + + // autoTester is run on a clone of the repository. We use relative paths, so we can use both local disk and GitHub + // For a test in "D:/GitHub/hifi_tests/tests/content/entity/zone/ambientLightInheritance" the + // GitHub URL is "./content/entity/zone/ambientLightInheritance?raw=true" + QString partialPath = directory.right(directory.length() - (directory.lastIndexOf("/tests/") + QString("/tests").length() + 1)); + QString url = "./" + partialPath; + + stream << prefix << "[" << directoryName << "](" << url << "?raw=true" << ")"; + QFileInfo fileInfo1(directory + "/test.md"); + if (fileInfo1.exists()) { + stream << " [(test description)](" << url << "/test.md)"; + } + + QFileInfo fileInfo2(directory + "/" + TEST_FILENAME); + if (fileInfo2.exists()) { stream << " (*)"; } stream << "\n"; From adcf99112596f0f802ddf8b79448f091be982251 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 11 Apr 2018 17:36:32 -0700 Subject: [PATCH 097/109] Improvements to profiling data capture Use code-provided task names for profile blocks; record QML URLs for loadInternal. --- libraries/gpu/src/gpu/Context.cpp | 2 +- libraries/qml/src/qml/OffscreenSurface.cpp | 2 +- libraries/render-utils/src/BloomEffect.cpp | 1 - .../render-utils/src/HighlightEffect.cpp | 1 - .../render-utils/src/RenderDeferredTask.cpp | 1 - .../render-utils/src/RenderForwardTask.cpp | 1 - .../render-utils/src/RenderShadowTask.cpp | 1 - libraries/render-utils/src/RenderViewTask.cpp | 1 - .../render-utils/src/UpdateSceneTask.cpp | 1 - libraries/render-utils/src/ZoneRenderer.cpp | 1 - libraries/render/src/render/Engine.cpp | 2 +- .../src/render/RenderFetchCullSortTask.cpp | 1 - libraries/task/src/task/Task.h | 55 ++++++++++--------- 13 files changed, 33 insertions(+), 37 deletions(-) diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index dc2273ecb6..7dc6965076 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -129,7 +129,7 @@ void Context::executeFrame(const FramePointer& frame) const { } bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings, const Shader::CompilationHandler& handler) { - PROFILE_RANGE(app, "makeProgram"); + PROFILE_RANGE_EX(app, "makeProgram", 0xff4040c0, shader.getID()); // If we're running in another DLL context, we need to fetch the program callback out of the application // FIXME find a way to do this without reliance on Qt app properties if (!_makeProgramCallback) { diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index 2f1b3910c6..2da1c41340 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -286,7 +286,7 @@ void OffscreenSurface::loadInternal(const QUrl& qmlSource, bool createNewContext, QQuickItem* parent, const QmlContextObjectCallback& callback) { - PROFILE_RANGE(app, "loadInternal"); + PROFILE_RANGE_EX(app, "OffscreenSurface::loadInternal", 0xffff00ff, 0, { std::make_pair("url", qmlSource.toDisplayString()) }); if (QThread::currentThread() != thread()) { qFatal("Called load on a non-surface thread"); } diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index 75ddb5f8e9..ddd63f012f 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -326,7 +326,6 @@ Bloom::Bloom() { } void Bloom::configure(const Config& config) { - PROFILE_RANGE(startup, "Bloom::build"); std::string blurName{ "BloomBlurN" }; for (auto i = 0; i < BLOOM_BLUR_LEVEL_COUNT; i++) { diff --git a/libraries/render-utils/src/HighlightEffect.cpp b/libraries/render-utils/src/HighlightEffect.cpp index 5876b40d2b..d151da766b 100644 --- a/libraries/render-utils/src/HighlightEffect.cpp +++ b/libraries/render-utils/src/HighlightEffect.cpp @@ -476,7 +476,6 @@ void DrawHighlightTask::configure(const Config& config) { } void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, render::Varying& outputs) { - PROFILE_RANGE(startup, "Bloom::build"); const auto items = inputs.getN(0).get(); const auto sceneFrameBuffer = inputs.getN(1); const auto primaryFramebuffer = inputs.getN(2); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 6d44e7f182..2377f5131f 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -76,7 +76,6 @@ const render::Varying RenderDeferredTask::addSelectItemJobs(JobModel& task, cons } void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { - PROFILE_RANGE(startup, "RenderDeferredTask::build"); const auto& items = input.get(); auto fadeEffect = DependencyManager::get(); diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index e7603d73d9..63370109e0 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -40,7 +40,6 @@ extern void initForwardPipelines(ShapePlumber& plumber, extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false); void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { - PROFILE_RANGE(startup, "RenderForwardTask::build"); auto items = input.get(); auto fadeEffect = DependencyManager::get(); diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 84fd46f429..69c5b3c689 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -215,7 +215,6 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) { ::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& bounds) { - PROFILE_RANGE(startup, "RenderShadowTask::build"); return _cullFunctor(args, bounds); }; diff --git a/libraries/render-utils/src/RenderViewTask.cpp b/libraries/render-utils/src/RenderViewTask.cpp index aed2972243..122fc16e61 100644 --- a/libraries/render-utils/src/RenderViewTask.cpp +++ b/libraries/render-utils/src/RenderViewTask.cpp @@ -17,7 +17,6 @@ void RenderViewTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cullFunctor, bool isDeferred, uint8_t tagBits, uint8_t tagMask) { // auto items = input.get(); - PROFILE_RANGE(startup, "RenderViewTask::build"); // Warning : the cull functor passed to the shadow pass should only be testing for LOD culling. If frustum culling // is performed, then casters not in the view frustum will be removed, which is not what we wish. task.addJob("RenderShadowTask", cullFunctor, tagBits, tagMask); diff --git a/libraries/render-utils/src/UpdateSceneTask.cpp b/libraries/render-utils/src/UpdateSceneTask.cpp index 2b4e626fed..e05f28ef0d 100644 --- a/libraries/render-utils/src/UpdateSceneTask.cpp +++ b/libraries/render-utils/src/UpdateSceneTask.cpp @@ -19,7 +19,6 @@ #include "DeferredLightingEffect.h" void UpdateSceneTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { - PROFILE_RANGE(startup, "UpdateSceneTask::build"); task.addJob("LightStageSetup"); task.addJob("BackgroundStageSetup"); task.addJob("HazeStageSetup"); diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index bd03668b11..51939efd4f 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -42,7 +42,6 @@ protected: const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) { - PROFILE_RANGE(startup, "ZoneRendererTask::build"); // Filter out the sorted list of zones const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index 463b45451b..b0842d63cd 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -36,7 +36,7 @@ public: } }; -Engine::Engine() : Task("Engine", EngineTask::JobModel::create()), +Engine::Engine() : Task(EngineTask::JobModel::create("Engine")), _renderContext(std::make_shared()) { } diff --git a/libraries/render/src/render/RenderFetchCullSortTask.cpp b/libraries/render/src/render/RenderFetchCullSortTask.cpp index 629bcf81bf..7b9765dca1 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.cpp +++ b/libraries/render/src/render/RenderFetchCullSortTask.cpp @@ -20,7 +20,6 @@ using namespace render; void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varying& output, CullFunctor cullFunctor, uint8_t tagBits, uint8_t tagMask) { cullFunctor = cullFunctor ? cullFunctor : [](const RenderArgs*, const AABox&){ return true; }; - PROFILE_RANGE(startup, "RenderFetchCullSortTask::build"); // CPU jobs: // Fetch and cull the items from the scene const ItemFilter filter = ItemFilter::Builder::visibleWorldItems().withoutLayered().withTagBits(tagBits, tagMask); diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 08df55dddd..7e4c8de51b 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -47,7 +47,7 @@ protected: bool _doAbortTask{ false }; }; -// JobContext class is the base calss for the context object which is passed through all the Job::run calls thoughout the graph of jobs +// JobContext class is the base class for the context object which is passed through all the Job::run calls thoughout the graph of jobs // It is used to communicate to the job::run its context and various state information the job relies on. // It specifically provide access to: // - The taskFlow object allowing for messaging control flow commands from within a Job::run @@ -73,19 +73,21 @@ class JobConcept { public: using Config = JobConfig; - JobConcept(QConfigPointer config) : _config(config) {} + JobConcept(const std::string& name, QConfigPointer config) : _name(name), _config(config) {} virtual ~JobConcept() = default; + + const std::string& getName() const { return _name; } virtual const Varying getInput() const { return Varying(); } virtual const Varying getOutput() const { return Varying(); } virtual QConfigPointer& getConfiguration() { return _config; } virtual void applyConfiguration() = 0; - void setCPURunTime(double mstime) { std::static_pointer_cast(_config)->setCPURunTime(mstime); } QConfigPointer _config; protected: + const std::string _name; }; @@ -122,7 +124,7 @@ public: class Concept : public JobConcept { public: - Concept(QConfigPointer config) : JobConcept(config) {} + Concept(const std::string& name, QConfigPointer config) : JobConcept(name, config) {} virtual ~Concept() = default; virtual void run(const ContextPointer& jobContext) = 0; @@ -143,8 +145,8 @@ public: const Varying getOutput() const override { return _output; } template - Model(const Varying& input, QConfigPointer config, A&&... args) : - Concept(config), + Model(const std::string& name, const Varying& input, QConfigPointer config, A&&... args) : + Concept(name, config), _data(Data(std::forward(args)...)), _input(input), _output(Output()) { @@ -152,12 +154,14 @@ public: } template - static std::shared_ptr create(const Varying& input, A&&... args) { - return std::make_shared(input, std::make_shared(), std::forward(args)...); + static std::shared_ptr create(const std::string& name, const Varying& input, A&&... args) { + return std::make_shared(name, input, std::make_shared(), std::forward(args)...); } void applyConfiguration() override { + Duration profileRange(trace_render(), ("configure::" + getName()).c_str()); + jobConfigure(_data, *std::static_pointer_cast(Concept::_config)); } @@ -173,8 +177,9 @@ public: template using ModelO = Model; template using ModelIO = Model; - Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {} + Job(ConceptPointer concept) : _concept(concept) {} + const std::string& getName() const { return _concept->getName(); } const Varying getInput() const { return _concept->getInput(); } const Varying getOutput() const { return _concept->getOutput(); } QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); } @@ -193,9 +198,9 @@ public: } virtual void run(const ContextPointer& jobContext) { - PerformanceTimer perfTimer(_name.c_str()); + PerformanceTimer perfTimer(getName().c_str()); // NOTE: rather than use the PROFILE_RANGE macro, we create a Duration manually - Duration profileRange(jobContext->profileCategory, _name.c_str()); + Duration profileRange(jobContext->profileCategory, ("run::" + getName()).c_str()); auto start = usecTimestampNow(); _concept->run(jobContext); @@ -203,11 +208,8 @@ public: _concept->setCPURunTime((double)(usecTimestampNow() - start) / 1000.0); } - const std::string& getName() const { return _name; } - protected: ConceptPointer _concept; - std::string _name = ""; }; @@ -230,7 +232,7 @@ public: using ConceptPointer = typename JobType::ConceptPointer; using Jobs = std::vector; - Task(std::string name, ConceptPointer concept) : JobType(name, concept) {} + Task(ConceptPointer concept) : JobType(concept) {} class TaskConcept : public Concept { public: @@ -259,11 +261,11 @@ public: return jobIt; } - TaskConcept(const Varying& input, QConfigPointer config) : Concept(config), _input(input) {} + TaskConcept(const std::string& name, const Varying& input, QConfigPointer config) : Concept(name, config), _input(input) {} // Create a new job in the container's queue; returns the job's output template const Varying addJob(std::string name, const Varying& input, NA&&... args) { - _jobs.emplace_back(name, (NT::JobModel::create(input, std::forward(args)...))); + _jobs.emplace_back((NT::JobModel::create(name, input, std::forward(args)...))); // Conect the child config to this task's config std::static_pointer_cast(Concept::getConfiguration())->connectChildConfig(_jobs.back().getConfiguration(), name); @@ -284,16 +286,18 @@ public: Data _data; - TaskModel(const Varying& input, QConfigPointer config) : - TaskConcept(input, config), + TaskModel(const std::string& name, const Varying& input, QConfigPointer config) : + TaskConcept(name, input, config), _data(Data()) {} template - static std::shared_ptr create(const Varying& input, A&&... args) { - auto model = std::make_shared(input, std::make_shared()); - - model->_data.build(*(model), model->_input, model->_output, std::forward(args)...); + static std::shared_ptr create(const std::string& name, const Varying& input, A&&... args) { + auto model = std::make_shared(name, input, std::make_shared()); + { + Duration profileRange(trace_render(), ("build::" + model->getName()).c_str()); + model->_data.build(*(model), model->_input, model->_output, std::forward(args)...); + } // Recreate the Config to use the templated type model->createConfiguration(); model->applyConfiguration(); @@ -302,9 +306,9 @@ public: } template - static std::shared_ptr create(A&&... args) { + static std::shared_ptr create(const std::string& name, A&&... args) { const auto input = Varying(Input()); - return create(input, std::forward(args)...); + return create(name, input, std::forward(args)...); } void createConfiguration() { @@ -326,6 +330,7 @@ public: } void applyConfiguration() override { + Duration profileRange(trace_render(), ("configure::" + getName()).c_str()); jobConfigure(_data, *std::static_pointer_cast(Concept::_config)); for (auto& job : TaskConcept::_jobs) { job.applyConfiguration(); From 888fca2127531ae6901e4d1eeb1af54504f4d8a1 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 11 Apr 2018 18:31:09 -0700 Subject: [PATCH 098/109] Qualify getName in task template to satisfy gcc --- libraries/task/src/task/Task.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 7e4c8de51b..413a940f62 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -330,7 +330,7 @@ public: } void applyConfiguration() override { - Duration profileRange(trace_render(), ("configure::" + getName()).c_str()); + Duration profileRange(trace_render(), ("configure::" + JobConcept::getName()).c_str()); jobConfigure(_data, *std::static_pointer_cast(Concept::_config)); for (auto& job : TaskConcept::_jobs) { job.applyConfiguration(); From 5fdcd12375db918aa0a5146fca9e05fc1b2ab2ff Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 12 Apr 2018 09:20:46 -0700 Subject: [PATCH 099/109] add baking of skyboxes --- tools/bake-tools/bake.py | 3 ++- tools/bake-tools/convertToRelativePaths.py | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/bake-tools/bake.py b/tools/bake-tools/bake.py index 4051b7a7ca..edbfdf9e9f 100644 --- a/tools/bake-tools/bake.py +++ b/tools/bake-tools/bake.py @@ -71,7 +71,8 @@ def bakeFilesInDirectory(directory, outputDirectory): absFilePath = os.path.abspath(filePath) outputFolder = os.path.join(outputDirectory, appendPath) print "Baking file: " + filename - bakeFile(absFilePath, outputFolder, 'png') + bakeType = os.path.splitext(filename)[1][1:] + bakeFile(absFilePath, outputFolder, bakeType) else: filePath = os.sep.join([root, filename]) absFilePath = os.path.abspath(filePath) diff --git a/tools/bake-tools/convertToRelativePaths.py b/tools/bake-tools/convertToRelativePaths.py index 2798e2849f..70a6a30cfb 100644 --- a/tools/bake-tools/convertToRelativePaths.py +++ b/tools/bake-tools/convertToRelativePaths.py @@ -6,7 +6,7 @@ def createAssetMapping(assetDirectory): baseDirectory = os.path.basename(os.path.normpath(assetDirectory)) for root, subfolder, filenames in os.walk(assetDirectory): for filename in filenames: - if not filename.endswith('.ktx'): + if not filename.endswith('.ktx') or os.path.basename(root) == 'skyboxes': substring = os.path.commonprefix([assetDirectory, root]) newPath = root.replace(substring, ''); filePath = os.sep.join([newPath, filename]) @@ -30,7 +30,7 @@ def handleURL(url): baseFilename = os.path.basename(url) filename = os.path.splitext(baseFilename)[0] newUrl = MAP[filename] - print newUrl + print url + ' -> ' + newUrl return newUrl def handleOptions(): @@ -43,8 +43,12 @@ def main(): argsLength = len(sys.argv) if argsLength == 3: jsonFile = sys.argv[1] - gzipFile = jsonFile + '.gz' assetDirectory = sys.argv[2] + inputFilename = os.path.basename(jsonFile); + absPath = os.path.abspath(assetDirectory) + finalPath = absPath.replace('\\', '/'); + gzipFile = finalPath + '/' + inputFilename + '.gz' + print gzipFile createAssetMapping(assetDirectory) f = open(jsonFile) data = json.load(f) From 74f7a33a74f6ec8d65ac28808f0c89048ef7f246 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 12 Apr 2018 09:24:32 -0700 Subject: [PATCH 100/109] undo some changes --- libraries/image/src/image/Image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index 0b4acb29c4..696e311495 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -37,7 +37,7 @@ bool DEV_DECIMATE_TEXTURES = false; std::atomic DECIMATED_TEXTURE_COUNT{ 0 }; std::atomic RECTIFIED_TEXTURE_COUNT{ 0 }; -static const auto& HDR_FORMAT = gpu::Element::COLOR_R11G11B10; +static const auto HDR_FORMAT = gpu::Element::COLOR_R11G11B10; static std::atomic compressColorTextures { false }; static std::atomic compressNormalTextures { false }; From 5c141aa5e99a8d9ae50c112fbef31c4a058f6d2d Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 12 Apr 2018 09:28:28 -0700 Subject: [PATCH 101/109] Add --disableWatchdog command-line option Watchdog still runs but doesn't abort on timeout. Also fixes for previous tracing improvements. --- interface/src/Application.cpp | 13 ++++++++++--- libraries/task/src/task/Task.h | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 11427fb1e6..e882909a7c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -399,7 +399,8 @@ public: static const int HEARTBEAT_SAMPLES = 100000; // ~5 seconds worth of samples // Set the heartbeat on launch - DeadlockWatchdogThread() { + DeadlockWatchdogThread(bool crashOnTrigger = true) + : _crashOnTrigger(crashOnTrigger) { setObjectName("Deadlock Watchdog"); // Give the heartbeat an initial value _heartbeat = usecTimestampNow(); @@ -490,7 +491,9 @@ public: // Don't actually crash in debug builds, in case this apparent deadlock is simply from // the developer actively debugging code #ifdef NDEBUG + if (_crashOnTrigger) { deadlockDetectionCrash(); + } #endif } } @@ -502,6 +505,8 @@ public: static std::atomic _maxElapsedAverage; static ThreadSafeMovingAverage _movingAverage; + const bool _crashOnTrigger; + bool _quit { false }; }; @@ -957,7 +962,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto steamClient = PluginManager::getInstance()->getSteamClientPlugin(); setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning())); setProperty(hifi::properties::CRASHED, _previousSessionCrashed); - + bool watchdogCrashWhenTriggered = true; { const QString TEST_SCRIPT = "--testScript"; const QStringList args = arguments(); @@ -967,6 +972,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (QFileInfo(testScriptPath).exists()) { setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); } + } else if (args.at(i) == QStringLiteral("--disableWatchdog")) { + watchdogCrashWhenTriggered = false; } } } @@ -1014,7 +1021,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // Set up a watchdog thread to intentionally crash the application on deadlocks if (!DISABLE_WATCHDOG) { - (new DeadlockWatchdogThread())->start(); + (new DeadlockWatchdogThread(watchdogCrashWhenTriggered))->start(); } // Set File Logger Session UUID diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 413a940f62..c07051fda1 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -73,7 +73,7 @@ class JobConcept { public: using Config = JobConfig; - JobConcept(const std::string& name, QConfigPointer config) : _name(name), _config(config) {} + JobConcept(const std::string& name, QConfigPointer config) : _config(config), _name(name) {} virtual ~JobConcept() = default; const std::string& getName() const { return _name; } @@ -330,7 +330,7 @@ public: } void applyConfiguration() override { - Duration profileRange(trace_render(), ("configure::" + JobConcept::getName()).c_str()); + Duration profileRange(trace_render(), ("configure::" + JobConcept::getName()).c_str()); jobConfigure(_data, *std::static_pointer_cast(Concept::_config)); for (auto& job : TaskConcept::_jobs) { job.applyConfiguration(); From a584d67acde3d39fd8cda702415529e0f2c2bfb9 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 12 Apr 2018 10:44:41 -0700 Subject: [PATCH 102/109] Tweaks for clang error and gcc warning --- interface/src/main.cpp | 2 +- libraries/task/src/task/Task.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 5f2afa9155..22db128f7e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -264,7 +264,7 @@ int main(int argc, const char* argv[]) { QTimer exitTimer; - if (traceDuration > 0.0) { + if (traceDuration > 0.0f) { exitTimer.setSingleShot(true); QObject::connect(&exitTimer, &QTimer::timeout, &app, &Application::quit); exitTimer.start(int(1000 * traceDuration)); diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index c07051fda1..022dd99200 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -160,7 +160,7 @@ public: void applyConfiguration() override { - Duration profileRange(trace_render(), ("configure::" + getName()).c_str()); + Duration profileRange(trace_render(), ("configure::" + JobConcept::getName()).c_str()); jobConfigure(_data, *std::static_pointer_cast(Concept::_config)); } From 568af7a0721f3febdff5bd82561c28e2e650b073 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 12 Apr 2018 11:24:26 -0700 Subject: [PATCH 103/109] Fix for avatar recording playback on avatars with many joints Before this fix, playback of avatar recording frames could overflow the maximum UDP packet size (MTU). This is playback of a recording was causing all the rotations and translations to be transmitted, even if the translations were not any different then the avatar default pose. This explicitly records the rotationIsDefaultPose and translationIsDefaultPose in the recording stream. This does not break backwards compatibility. However, it does require new recordings for avatars with large numbers of bones. --- libraries/avatars/src/AvatarData.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 1bbc8cc1a5..cd8ca5c547 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2060,22 +2060,30 @@ static const QString JSON_AVATAR_VERSION = QStringLiteral("version"); static const int JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION = 0; static const int JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION = 1; +static const int JSON_AVATAR_JOINT_DEFAULT_POSE_BITS_VERSION = 2; QJsonValue toJsonValue(const JointData& joint) { QJsonArray result; result.push_back(toJsonValue(joint.rotation)); result.push_back(toJsonValue(joint.translation)); + result.push_back(QJsonValue(joint.rotationIsDefaultPose)); + result.push_back(QJsonValue(joint.translationIsDefaultPose)); return result; } -JointData jointDataFromJsonValue(const QJsonValue& json) { +JointData jointDataFromJsonValue(int version, const QJsonValue& json) { JointData result; if (json.isArray()) { QJsonArray array = json.toArray(); result.rotation = quatFromJsonValue(array[0]); - result.rotationIsDefaultPose = false; result.translation = vec3FromJsonValue(array[1]); - result.translationIsDefaultPose = false; + if (version >= JSON_AVATAR_JOINT_DEFAULT_POSE_BITS_VERSION) { + result.rotationIsDefaultPose = array[2].toBool(); + result.translationIsDefaultPose = array[3].toBool(); + } else { + result.rotationIsDefaultPose = false; + result.translationIsDefaultPose = false; + } } return result; } @@ -2083,7 +2091,7 @@ JointData jointDataFromJsonValue(const QJsonValue& json) { QJsonObject AvatarData::toJson() const { QJsonObject root; - root[JSON_AVATAR_VERSION] = JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION; + root[JSON_AVATAR_VERSION] = JSON_AVATAR_JOINT_DEFAULT_POSE_BITS_VERSION; if (!getSkeletonModelURL().isEmpty()) { root[JSON_AVATAR_BODY_MODEL] = getSkeletonModelURL().toString(); @@ -2247,7 +2255,7 @@ void AvatarData::fromJson(const QJsonObject& json, bool useFrameSkeleton) { QJsonArray jointArrayJson = json[JSON_AVATAR_JOINT_ARRAY].toArray(); jointArray.reserve(jointArrayJson.size()); for (const auto& jointJson : jointArrayJson) { - auto joint = jointDataFromJsonValue(jointJson); + auto joint = jointDataFromJsonValue(version, jointJson); jointArray.push_back(joint); } setRawJointData(jointArray); @@ -2558,4 +2566,4 @@ void AvatarEntityMapFromScriptValue(const QScriptValue& object, AvatarEntityMap& value[EntityID] = binaryEntityProperties; } -} \ No newline at end of file +} From 2593d224c518f08a97e5ba41659759c1c2530268 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 12 Apr 2018 13:24:31 -0700 Subject: [PATCH 104/109] CR feedback --- assignment-client/src/audio/AudioMixerSlave.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index e0c7e71589..3c8e38f278 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -327,9 +327,11 @@ void AudioMixerSlave::addStream(AudioMixerClientData& listenerNodeData, const QU auto& hrtf = listenerNodeData.hrtfForStream(sourceNodeID, streamToAdd.getStreamIdentifier()); gain *= hrtf.getGainAdjustment(); + const float scale = 1/32768.0f; // int16_t to float + for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; i++) { - _mixSamples[2*i+0] += (float)streamPopOutput[2*i+0] * gain * (1/32768.0f); - _mixSamples[2*i+1] += (float)streamPopOutput[2*i+1] * gain * (1/32768.0f); + _mixSamples[2*i+0] += (float)streamPopOutput[2*i+0] * gain * scale; + _mixSamples[2*i+1] += (float)streamPopOutput[2*i+1] * gain * scale; } ++stats.manualStereoMixes; @@ -338,8 +340,11 @@ void AudioMixerSlave::addStream(AudioMixerClientData& listenerNodeData, const QU // echo sources are not passed through HRTF if (isEcho) { + + const float scale = 1/32768.0f; // int16_t to float + for (int i = 0; i < AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; i++) { - float sample = (float)streamPopOutput[i] * gain * (1/32768.0f); + float sample = (float)streamPopOutput[i] * gain * scale; _mixSamples[2*i+0] += sample; _mixSamples[2*i+1] += sample; } From da319b9af62f51a815ce8319491528366d30e688 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 12 Apr 2018 15:09:01 -0700 Subject: [PATCH 105/109] Changed version constants into a enum class, to fix macosx warnings. --- libraries/avatars/src/AvatarData.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index cd8ca5c547..08eee947ef 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2058,9 +2058,11 @@ static const QString JSON_AVATAR_ENTITIES = QStringLiteral("attachedEntities"); static const QString JSON_AVATAR_SCALE = QStringLiteral("scale"); static const QString JSON_AVATAR_VERSION = QStringLiteral("version"); -static const int JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION = 0; -static const int JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION = 1; -static const int JSON_AVATAR_JOINT_DEFAULT_POSE_BITS_VERSION = 2; +enum class JsonAvatarFrameVersion : int { + JointRotationsInRelativeFrame = 0, + JointRotationsInAbsoluteFrame, + JointDefaultPoseBits +}; QJsonValue toJsonValue(const JointData& joint) { QJsonArray result; @@ -2077,7 +2079,7 @@ JointData jointDataFromJsonValue(int version, const QJsonValue& json) { QJsonArray array = json.toArray(); result.rotation = quatFromJsonValue(array[0]); result.translation = vec3FromJsonValue(array[1]); - if (version >= JSON_AVATAR_JOINT_DEFAULT_POSE_BITS_VERSION) { + if (version >= (int)JsonAvatarFrameVersion::JointDefaultPoseBits) { result.rotationIsDefaultPose = array[2].toBool(); result.translationIsDefaultPose = array[3].toBool(); } else { @@ -2091,7 +2093,7 @@ JointData jointDataFromJsonValue(int version, const QJsonValue& json) { QJsonObject AvatarData::toJson() const { QJsonObject root; - root[JSON_AVATAR_VERSION] = JSON_AVATAR_JOINT_DEFAULT_POSE_BITS_VERSION; + root[JSON_AVATAR_VERSION] = (int)JsonAvatarFrameVersion::JointDefaultPoseBits; if (!getSkeletonModelURL().isEmpty()) { root[JSON_AVATAR_BODY_MODEL] = getSkeletonModelURL().toString(); @@ -2166,7 +2168,7 @@ void AvatarData::fromJson(const QJsonObject& json, bool useFrameSkeleton) { version = json[JSON_AVATAR_VERSION].toInt(); } else { // initial data did not have a version field. - version = JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION; + version = (int)JsonAvatarFrameVersion::JointRotationsInRelativeFrame; } if (json.contains(JSON_AVATAR_BODY_MODEL)) { @@ -2243,7 +2245,7 @@ void AvatarData::fromJson(const QJsonObject& json, bool useFrameSkeleton) { // } if (json.contains(JSON_AVATAR_JOINT_ARRAY)) { - if (version == JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION) { + if (version == (int)JsonAvatarFrameVersion::JointRotationsInRelativeFrame) { // because we don't have the full joint hierarchy skeleton of the model, // we can't properly convert from relative rotations into absolute rotations. quint64 now = usecTimestampNow(); From 157ca8cd681efdf7af42d1c00ff4ac8ac2246fe6 Mon Sep 17 00:00:00 2001 From: Clement Date: Thu, 12 Apr 2018 16:20:47 -0700 Subject: [PATCH 106/109] Update docs with correct qt version --- BUILD.md | 8 ++++---- BUILD_LINUX.md | 8 ++++---- BUILD_OSX.md | 2 +- BUILD_WIN.md | 20 ++++++++++---------- cmake/macros/SetupQt.cmake | 12 ++++++------ interface/src/Application.cpp | 18 +++++++++--------- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/BUILD.md b/BUILD.md index feed677828..ba38f4b51d 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,7 +1,7 @@ ### Dependencies - [cmake](https://cmake.org/download/): 3.9 -- [Qt](https://www.qt.io/download-open-source): 5.9.1 +- [Qt](https://www.qt.io/download-open-source): 5.10.1 - [OpenSSL](https://www.openssl.org/): Use the latest available 1.0 version (**NOT** 1.1) of OpenSSL to avoid security vulnerabilities. - [VHACD](https://github.com/virneo/v-hacd)(clone this repository)(Optional) @@ -46,8 +46,8 @@ This can either be entered directly into your shell session before you build or The path it needs to be set to will depend on where and how Qt5 was installed. e.g. - export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.6.2/clang_64/lib/cmake/ - export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.6.2/lib/cmake + export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.10.1/clang_64/lib/cmake/ + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.10.1/lib/cmake export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake #### Generating build files @@ -66,7 +66,7 @@ Any variables that need to be set for CMake to find dependencies can be set as E For example, to pass the QT_CMAKE_PREFIX_PATH variable during build file generation: - cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.6.2/lib/cmake + cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.10.1/lib/cmake #### Finding Dependencies diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 038f53154c..64c0e9a643 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -14,8 +14,8 @@ Should you choose not to install Qt5 via a package manager that handles dependen Install qt: ```bash -wget http://debian.highfidelity.com/pool/h/hi/hifi-qt5.6.1_5.6.1_amd64.deb -sudo dpkg -i hifi-qt5.6.1_5.6.1_amd64.deb +wget http://debian.highfidelity.com/pool/h/hi/hifi-qt5.10.1_5.10.1_amd64.deb +sudo dpkg -i hifi-qt5.10.1_5.10.1_amd64.deb ``` Install build dependencies: @@ -66,7 +66,7 @@ cd hifi/build Prepare makefiles: ```bash -cmake -DQT_CMAKE_PREFIX_PATH=/usr/local/Qt5.6.1/5.6/gcc_64/lib/cmake .. +cmake -DQT_CMAKE_PREFIX_PATH=/usr/local/Qt5.10.1/5.10/gcc_64/lib/cmake .. ``` Start compilation and get a cup of coffee: @@ -74,7 +74,7 @@ Start compilation and get a cup of coffee: make domain-server assignment-client interface ``` -In a server does not make sense to compile interface +In a server does not make sense to compile interface ### Running the software diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 6b66863534..62102b3e18 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -20,7 +20,7 @@ Note that this uses the version from the homebrew formula at the time of this wr Assuming you've installed Qt using the homebrew instructions above, you'll need to set QT_CMAKE_PREFIX_PATH so CMake can find your installations. For Qt installed via homebrew, set QT_CMAKE_PREFIX_PATH: - export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt/5.9.1/lib/cmake + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt/5.10.1/lib/cmake Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change. diff --git a/BUILD_WIN.md b/BUILD_WIN.md index eea1f85e5b..3222e75c66 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -1,13 +1,13 @@ This is a stand-alone guide for creating your first High Fidelity build for Windows 64-bit. ## Building High Fidelity -Note: We are now using Visual Studio 2017 and Qt 5.9.1. If you are upgrading from Visual Studio 2013 and Qt 5.6.2, do a clean uninstall of those versions before going through this guide. +Note: We are now using Visual Studio 2017 and Qt 5.10.1. If you are upgrading from Visual Studio 2013 and Qt 5.6.2, do a clean uninstall of those versions before going through this guide. Note: The prerequisites will require about 10 GB of space on your drive. You will also need a system with at least 8GB of main memory. ### Step 1. Visual Studio 2017 -If you don’t have Community or Professional edition of Visual Studio 2017, download [Visual Studio Community 2017](https://www.visualstudio.com/downloads/). +If you don’t have Community or Professional edition of Visual Studio 2017, download [Visual Studio Community 2017](https://www.visualstudio.com/downloads/). When selecting components, check "Desktop development with C++." Also check "Windows 8.1 SDK and UCRT SDK" and "VC++ 2015.3 v140 toolset (x86,x64)" on the Summary toolbar on the right. @@ -17,15 +17,15 @@ Download and install the latest version of CMake 3.9. Download the file named w ### Step 3. Installing Qt -Download and install the [Qt Online Installer](https://www.qt.io/download-open-source/?hsCtaTracking=f977210e-de67-475f-a32b-65cec207fd03%7Cd62710cd-e1db-46aa-8d4d-2f1c1ffdacea). While installing, you only need to have the following components checked under Qt 5.9.1: "msvc2017 64-bit", "Qt WebEngine", and "Qt Script (Deprecated)". +Download and install the [Qt Online Installer](https://www.qt.io/download-open-source/?hsCtaTracking=f977210e-de67-475f-a32b-65cec207fd03%7Cd62710cd-e1db-46aa-8d4d-2f1c1ffdacea). While installing, you only need to have the following components checked under Qt 5.10.1: "msvc2017 64-bit", "Qt WebEngine", and "Qt Script (Deprecated)". -Note: Installing the Sources is optional but recommended if you have room for them (~2GB). +Note: Installing the Sources is optional but recommended if you have room for them (~2GB). ### Step 4. Setting Qt Environment Variable Go to `Control Panel > System > Advanced System Settings > Environment Variables > New...` (or search “Environment Variables” in Start Search). * Set "Variable name": `QT_CMAKE_PREFIX_PATH` -* Set "Variable value": `C:\Qt\5.9.1\msvc2017_64\lib\cmake` +* Set "Variable value": `C:\Qt\5.10.1\msvc2017_64\lib\cmake` ### Step 5. Installing [vcpkg](https://github.com/Microsoft/vcpkg) @@ -39,7 +39,7 @@ Go to `Control Panel > System > Advanced System Settings > Environment Variables * In the vcpkg directory, install the 64 bit OpenSSL package with the command `vcpkg install openssl:x64-windows` * Once the build completes you should have a file `ssl.h` in `${VCPKG_ROOT}/installed/x64-windows/include/openssl` - + ### Step 7. Running CMake to Generate Build Files Run Command Prompt from Start and run the following commands: @@ -49,7 +49,7 @@ mkdir build cd build cmake .. -G "Visual Studio 15 Win64" ``` - + Where `%HIFI_DIR%` is the directory for the highfidelity repository. ### Step 8. Making a Build @@ -74,10 +74,10 @@ Note: You can also run Interface by launching it from command line or File Explo ## Troubleshooting -For any problems after Step #7, first try this: +For any problems after Step #7, first try this: * Delete your locally cloned copy of the highfidelity repository * Restart your computer -* Redownload the [repository](https://github.com/highfidelity/hifi) +* Redownload the [repository](https://github.com/highfidelity/hifi) * Restart directions from Step #7 #### CMake gives you the same error message repeatedly after the build fails @@ -90,4 +90,4 @@ Remove `CMakeCache.txt` found in the `%HIFI_DIR%\build` directory. Verify that #### Qt is throwing an error -Make sure you have the correct version (5.9.1) installed and `QT_CMAKE_PREFIX_PATH` environment variable is set correctly. +Make sure you have the correct version (5.10.1) installed and `QT_CMAKE_PREFIX_PATH` environment variable is set correctly. diff --git a/cmake/macros/SetupQt.cmake b/cmake/macros/SetupQt.cmake index 00a398761b..71f5314d2f 100644 --- a/cmake/macros/SetupQt.cmake +++ b/cmake/macros/SetupQt.cmake @@ -1,10 +1,10 @@ -# +# # Created by Bradley Austin Davis on 2017/09/02 # Copyright 2013-2017 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 -# +# # Construct a default QT location from a root path, a version and an architecture function(calculate_default_qt_dir _RESULT_NAME) @@ -27,7 +27,7 @@ function(calculate_default_qt_dir _RESULT_NAME) endif() set_from_env(QT_ROOT QT_ROOT ${QT_DEFAULT_ROOT}) - set_from_env(QT_VERSION QT_VERSION "5.9.1") + set_from_env(QT_VERSION QT_VERSION "5.10.1") set_from_env(QT_ARCH QT_ARCH ${QT_DEFAULT_ARCH}) set(${_RESULT_NAME} "${QT_ROOT}/${QT_VERSION}/${QT_ARCH}" PARENT_SCOPE) @@ -60,11 +60,11 @@ macro(setup_qt) #if (NOT EXISTS "${QT_DIR}/include/QtCore/QtGlobal") # message(FATAL_ERROR "Unable to locate Qt includes in ${QT_DIR}") #endif() - + if (NOT EXISTS "${QT_CMAKE_PREFIX_PATH}/Qt5Core/Qt5CoreConfig.cmake") message(FATAL_ERROR "Unable to locate Qt cmake config in ${QT_CMAKE_PREFIX_PATH}") endif() - + message(STATUS "The Qt build in use is: \"${QT_DIR}\"") # Instruct CMake to run moc automatically when needed. @@ -72,7 +72,7 @@ macro(setup_qt) # Instruct CMake to run rcc automatically when needed set(CMAKE_AUTORCC ON) - + if (WIN32) add_paths_to_fixup_libs("${QT_DIR}/bin") endif () diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 343074f61c..aec31f2de4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -225,8 +225,8 @@ #ifdef DEBUG_EVENT_QUEUE // This is a HACK that uses private headers included with the qt source distrubution. // To use this feature you need to add these directores to your include path: -// E:/Qt/5.9.1/Src/qtbase/include/QtCore/5.9.1/QtCore -// E:/Qt/5.9.1/Src/qtbase/include/QtCore/5.9.1 +// E:/Qt/5.10.1/Src/qtbase/include/QtCore/5.10.1/QtCore +// E:/Qt/5.10.1/Src/qtbase/include/QtCore/5.10.1 #define QT_BOOTSTRAPPED #include #include @@ -2038,7 +2038,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo }); _snapshotSound = DependencyManager::get()->getSound(PathUtils::resourcesUrl("sounds/snap.wav")); - + QVariant testProperty = property(hifi::properties::TEST); qDebug() << testProperty; if (testProperty.isValid()) { @@ -6577,7 +6577,7 @@ void Application::addAssetToWorldFromURL(QString url) { } else { filename.remove(".zip"); } - + } if (!DependencyManager::get()->getThisNodeCanWriteAssets()) { @@ -6751,7 +6751,7 @@ void Application::addAssetToWorldSetMapping(QString filePath, QString mapping, Q addAssetToWorldError(filenameFromPath(filePath), errorInfo); } else { // to prevent files that aren't models or texture files from being loaded into world automatically - if ((filePath.toLower().endsWith(OBJ_EXTENSION) || filePath.toLower().endsWith(FBX_EXTENSION)) || + if ((filePath.toLower().endsWith(OBJ_EXTENSION) || filePath.toLower().endsWith(FBX_EXTENSION)) || ((filePath.toLower().endsWith(JPG_EXTENSION) || filePath.toLower().endsWith(PNG_EXTENSION)) && ((!isBlocks) && (!isZip)))) { addAssetToWorldAddEntity(filePath, mapping); @@ -7400,8 +7400,8 @@ bool Application::isThrottleRendering() const { bool Application::hasFocus() const { bool result = (QApplication::activeWindow() != nullptr); #if defined(Q_OS_WIN) - // On Windows, QWidget::activateWindow() - as called in setFocus() - makes the application's taskbar icon flash but doesn't - // take user focus away from their current window. So also check whether the application is the user's current foreground + // On Windows, QWidget::activateWindow() - as called in setFocus() - makes the application's taskbar icon flash but doesn't + // take user focus away from their current window. So also check whether the application is the user's current foreground // window. result = result && (HWND)QApplication::activeWindow()->winId() == GetForegroundWindow(); #endif @@ -7409,7 +7409,7 @@ bool Application::hasFocus() const { } void Application::setFocus() { - // Note: Windows doesn't allow a user focus to be taken away from another application. Instead, it changes the color of and + // Note: Windows doesn't allow a user focus to be taken away from another application. Instead, it changes the color of and // flashes the taskbar icon. auto window = qApp->getWindow(); window->activateWindow(); @@ -7650,7 +7650,7 @@ void Application::updateDisplayMode() { menu->setIsOptionChecked(MenuOption::FirstPerson, true); cameraMenuChanged(); } - + // Remove the mirror camera option from menu if in HMD mode auto mirrorAction = menu->getActionForOption(MenuOption::FullscreenMirror); mirrorAction->setVisible(!isHmd); From 76468f7f261184a96ee5967c973b22b3dad75d13 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 12 Apr 2018 16:58:13 -0700 Subject: [PATCH 107/109] Use existing DISABLE_WATCHDOG global to turn off thread entirely --- interface/src/Application.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e882909a7c..5b2b9b9ac6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -399,8 +399,7 @@ public: static const int HEARTBEAT_SAMPLES = 100000; // ~5 seconds worth of samples // Set the heartbeat on launch - DeadlockWatchdogThread(bool crashOnTrigger = true) - : _crashOnTrigger(crashOnTrigger) { + DeadlockWatchdogThread() { setObjectName("Deadlock Watchdog"); // Give the heartbeat an initial value _heartbeat = usecTimestampNow(); @@ -491,9 +490,7 @@ public: // Don't actually crash in debug builds, in case this apparent deadlock is simply from // the developer actively debugging code #ifdef NDEBUG - if (_crashOnTrigger) { - deadlockDetectionCrash(); - } + deadlockDetectionCrash(); #endif } } @@ -505,8 +502,6 @@ public: static std::atomic _maxElapsedAverage; static ThreadSafeMovingAverage _movingAverage; - const bool _crashOnTrigger; - bool _quit { false }; }; @@ -962,7 +957,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto steamClient = PluginManager::getInstance()->getSteamClientPlugin(); setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning())); setProperty(hifi::properties::CRASHED, _previousSessionCrashed); - bool watchdogCrashWhenTriggered = true; { const QString TEST_SCRIPT = "--testScript"; const QStringList args = arguments(); @@ -972,8 +966,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (QFileInfo(testScriptPath).exists()) { setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); } - } else if (args.at(i) == QStringLiteral("--disableWatchdog")) { - watchdogCrashWhenTriggered = false; } } } @@ -1019,9 +1011,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto nodeList = DependencyManager::get(); nodeList->startThread(); + const char** constArgv = const_cast(argv); + if (cmdOptionExists(argc, constArgv, "--disableWatchdog")) { + DISABLE_WATCHDOG = true; + } // Set up a watchdog thread to intentionally crash the application on deadlocks if (!DISABLE_WATCHDOG) { - (new DeadlockWatchdogThread(watchdogCrashWhenTriggered))->start(); + (new DeadlockWatchdogThread())->start(); } // Set File Logger Session UUID @@ -1228,7 +1224,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(&_entityEditSender, &EntityEditPacketSender::packetSent, this, &Application::packetSent); connect(&_entityEditSender, &EntityEditPacketSender::addingEntityWithCertificate, this, &Application::addingEntityWithCertificate); - const char** constArgv = const_cast(argv); QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads"); bool success; int concurrentDownloads = concurrentDownloadsStr.toInt(&success); From ee6e9ee81e1f6b339585652092abba1dc63de68c Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Fri, 13 Apr 2018 10:36:13 -0700 Subject: [PATCH 108/109] Remove dead code left over from Gverb --- cmake/modules/FindGverb.cmake | 25 ----------- script-archive/example/audio/audioReverbOn.js | 43 ------------------- 2 files changed, 68 deletions(-) delete mode 100644 cmake/modules/FindGverb.cmake delete mode 100644 script-archive/example/audio/audioReverbOn.js diff --git a/cmake/modules/FindGverb.cmake b/cmake/modules/FindGverb.cmake deleted file mode 100644 index 0c149a7ca1..0000000000 --- a/cmake/modules/FindGverb.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# FindGVerb.cmake -# -# Try to find the Gverb library. -# -# You must provide a GVERB_ROOT_DIR which contains src and include directories -# -# Once done this will define -# -# GVERB_FOUND - system found Gverb -# GVERB_INCLUDE_DIRS - the Gverb include directory -# -# Copyright 2014 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 -# - -include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") -hifi_library_search_hints("gverb") - -find_path(GVERB_INCLUDE_DIRS gverb.h PATH_SUFFIXES include HINTS ${GVERB_SEARCH_DIRS}) -find_library(GVERB_LIBRARIES gverb PATH_SUFFIXES lib HINTS ${GVERB_SEARCH_DIRS}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Gverb DEFAULT_MSG GVERB_INCLUDE_DIRS GVERB_LIBRARIES) \ No newline at end of file diff --git a/script-archive/example/audio/audioReverbOn.js b/script-archive/example/audio/audioReverbOn.js deleted file mode 100644 index 72f2fa97bc..0000000000 --- a/script-archive/example/audio/audioReverbOn.js +++ /dev/null @@ -1,43 +0,0 @@ -// -// audioReverbOn.js -// examples -// -// Copyright 2014 High Fidelity, Inc. -// -// -// Gives the ability to be set various reverb settings. -// -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - -// http://wiki.audacityteam.org/wiki/GVerb#Instant_reverb_settings -var audioOptions = new AudioEffectOptions({ - // Square Meters - maxRoomSize: 50, - roomSize: 50, - - // Seconds - reverbTime: 10, - - // Between 0 - 1 - damping: 0.50, - inputBandwidth: 0.75, - - // dB - earlyLevel: -22, - tailLevel: -28, - dryLevel: 0, - wetLevel: 6 -}); - -AudioDevice.setReverbOptions(audioOptions); -AudioDevice.setReverb(true); -print("Reverb is now on with the updated options."); - -function scriptEnding() { - AudioDevice.setReverb(false); - print("Reberb is now off."); -} - -Script.scriptEnding.connect(scriptEnding); \ No newline at end of file From 8005547d03d9c495d5f516191312c6b2460e3ebb Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 13 Apr 2018 13:52:19 -0700 Subject: [PATCH 109/109] rollback some qml changes on android --- .../qml/controls-uit/+android/Button.qml | 125 +++ .../qml/controls-uit/+android/Table.qml | 165 ++++ .../qml/desktop/+android/Desktop.qml | 575 ++++++++++++ .../dialogs/+android/CustomQueryDialog.qml | 338 +++++++ .../qml/dialogs/+android/FileDialog.qml | 840 ++++++++++++++++++ .../qml/dialogs/+android/QueryDialog.qml | 231 +++++ .../+android/AssetDialogContent.qml | 533 +++++++++++ 7 files changed, 2807 insertions(+) create mode 100644 interface/resources/qml/controls-uit/+android/Button.qml create mode 100644 interface/resources/qml/controls-uit/+android/Table.qml create mode 100644 interface/resources/qml/desktop/+android/Desktop.qml create mode 100644 interface/resources/qml/dialogs/+android/CustomQueryDialog.qml create mode 100644 interface/resources/qml/dialogs/+android/FileDialog.qml create mode 100644 interface/resources/qml/dialogs/+android/QueryDialog.qml create mode 100644 interface/resources/qml/dialogs/assetDialog/+android/AssetDialogContent.qml diff --git a/interface/resources/qml/controls-uit/+android/Button.qml b/interface/resources/qml/controls-uit/+android/Button.qml new file mode 100644 index 0000000000..2f05b35685 --- /dev/null +++ b/interface/resources/qml/controls-uit/+android/Button.qml @@ -0,0 +1,125 @@ +// +// Button.qml +// +// Created by David Rowe on 16 Feb 2016 +// Copyright 2016 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.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 +import TabletScriptingInterface 1.0 + +import "../styles-uit" + +Original.Button { + id: root; + + property int color: 0 + property int colorScheme: hifi.colorSchemes.light + property string buttonGlyph: ""; + + width: hifi.dimensions.buttonWidth + height: hifi.dimensions.controlLineHeight + + HifiConstants { id: hifi } + + onHoveredChanged: { + if (hovered) { + Tablet.playSound(TabletEnums.ButtonHover); + } + } + + onFocusChanged: { + if (focus) { + Tablet.playSound(TabletEnums.ButtonHover); + } + } + + onClicked: { + Tablet.playSound(TabletEnums.ButtonClick); + } + + style: ButtonStyle { + + background: Rectangle { + radius: hifi.buttons.radius + + border.width: (control.color === hifi.buttons.none || + (control.color === hifi.buttons.noneBorderless && control.hovered) || + (control.color === hifi.buttons.noneBorderlessWhite && control.hovered) || + (control.color === hifi.buttons.noneBorderlessGray && control.hovered)) ? 1 : 0; + border.color: control.color === hifi.buttons.noneBorderless ? hifi.colors.blueHighlight : + (control.color === hifi.buttons.noneBorderlessGray ? hifi.colors.baseGray : hifi.colors.white); + + gradient: Gradient { + GradientStop { + position: 0.2 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorStart[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else if (!control.hovered && control.focus) { + hifi.buttons.focusedColor[control.color] + } else { + hifi.buttons.colorStart[control.color] + } + } + } + GradientStop { + position: 1.0 + color: { + if (!control.enabled) { + hifi.buttons.disabledColorFinish[control.colorScheme] + } else if (control.pressed) { + hifi.buttons.pressedColor[control.color] + } else if (control.hovered) { + hifi.buttons.hoveredColor[control.color] + } else if (!control.hovered && control.focus) { + hifi.buttons.focusedColor[control.color] + } else { + hifi.buttons.colorFinish[control.color] + } + } + } + } + } + + label: Item { + HiFiGlyphs { + id: buttonGlyph; + visible: root.buttonGlyph !== ""; + text: root.buttonGlyph === "" ? hifi.glyphs.question : root.buttonGlyph; + // Size + size: 34; + // Anchors + anchors.right: buttonText.left; + anchors.top: parent.top; + anchors.bottom: parent.bottom; + // Style + color: enabled ? hifi.buttons.textColor[control.color] + : hifi.buttons.disabledTextColor[control.colorScheme]; + // Alignment + horizontalAlignment: Text.AlignHCenter; + verticalAlignment: Text.AlignVCenter; + } + RalewayBold { + id: buttonText; + anchors.centerIn: parent; + font.capitalization: Font.AllUppercase + color: enabled ? hifi.buttons.textColor[control.color] + : hifi.buttons.disabledTextColor[control.colorScheme] + size: hifi.fontSizes.buttonLabel + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: control.text + } + } + } +} diff --git a/interface/resources/qml/controls-uit/+android/Table.qml b/interface/resources/qml/controls-uit/+android/Table.qml new file mode 100644 index 0000000000..3c1d0fcd3c --- /dev/null +++ b/interface/resources/qml/controls-uit/+android/Table.qml @@ -0,0 +1,165 @@ +// +// Table.qml +// +// Created by David Rowe on 18 Feb 2016 +// Copyright 2016 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.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Controls 2.2 as QQC2 + +import "../styles-uit" + +TableView { + id: tableView + + property int colorScheme: hifi.colorSchemes.light + readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light + property bool expandSelectedRow: false + property bool centerHeaderText: false + readonly property real headerSpacing: 3 //spacing between sort indicator and table header title + property var titlePaintedPos: [] // storing extra data position behind painted + // title text and sort indicatorin table's header + signal titlePaintedPosSignal(int column) //signal that extradata position gets changed + + model: ListModel { } + + Component.onCompleted: { + if (flickableItem !== null && flickableItem !== undefined) { + tableView.flickableItem.QQC2.ScrollBar.vertical = scrollbar + } + } + + QQC2.ScrollBar { + id: scrollbar + parent: tableView.flickableItem + policy: QQC2.ScrollBar.AsNeeded + orientation: Qt.Vertical + visible: size < 1.0 + topPadding: tableView.headerVisible ? hifi.dimensions.tableHeaderHeight + 1 : 1 + anchors.top: tableView.top + anchors.left: tableView.right + anchors.bottom: tableView.bottom + + background: Item { + implicitWidth: hifi.dimensions.scrollbarBackgroundWidth + Rectangle { + anchors { + fill: parent; + topMargin: tableView.headerVisible ? hifi.dimensions.tableHeaderHeight : 0 + } + color: isLightColorScheme ? hifi.colors.tableScrollBackgroundLight + : hifi.colors.tableScrollBackgroundDark + } + } + + contentItem: Item { + implicitWidth: hifi.dimensions.scrollbarHandleWidth + Rectangle { + anchors.fill: parent + radius: (width - 4)/2 + color: isLightColorScheme ? hifi.colors.tableScrollHandleLight : hifi.colors.tableScrollHandleDark + } + } + } + + headerVisible: false + headerDelegate: Rectangle { + height: hifi.dimensions.tableHeaderHeight + color: isLightColorScheme ? hifi.colors.tableBackgroundLight : hifi.colors.tableBackgroundDark + + + RalewayRegular { + id: titleText + x: centerHeaderText ? (parent.width - paintedWidth - + ((sortIndicatorVisible && + sortIndicatorColumn === styleData.column) ? + (titleSort.paintedWidth / 5 + tableView.headerSpacing) : 0)) / 2 : + hifi.dimensions.tablePadding + text: styleData.value + size: hifi.fontSizes.tableHeading + font.capitalization: Font.AllUppercase + color: hifi.colors.baseGrayHighlight + horizontalAlignment: (centerHeaderText ? Text.AlignHCenter : Text.AlignLeft) + anchors.verticalCenter: parent.verticalCenter + } + + //actual image of sort indicator in glyph font only 20% of real font size + //i.e. if the charachter size set to 60 pixels, actual image is 12 pixels + HiFiGlyphs { + id: titleSort + text: sortIndicatorOrder == Qt.AscendingOrder ? hifi.glyphs.caratUp : hifi.glyphs.caratDn + color: hifi.colors.darkGray + opacity: 0.6; + size: hifi.fontSizes.tableHeadingIcon + anchors.verticalCenter: titleText.verticalCenter + anchors.left: titleText.right + anchors.leftMargin: -(hifi.fontSizes.tableHeadingIcon / 2.5) + tableView.headerSpacing + visible: sortIndicatorVisible && sortIndicatorColumn === styleData.column + onXChanged: { + titlePaintedPos[styleData.column] = titleText.x + titleText.paintedWidth + + paintedWidth / 5 + tableView.headerSpacing*2 + titlePaintedPosSignal(styleData.column) + } + } + + Rectangle { + width: 1 + anchors { + left: parent.left + top: parent.top + topMargin: 1 + bottom: parent.bottom + bottomMargin: 2 + } + color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight + visible: styleData.column > 0 + } + + Rectangle { + height: 1 + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight + } + } + + // Use rectangle to draw border with rounded corners. + frameVisible: false + Rectangle { + color: "#00000000" + anchors { fill: parent; margins: -2 } + border.color: isLightColorScheme ? hifi.colors.lightGrayText : hifi.colors.baseGrayHighlight + border.width: 2 + } + anchors.margins: 2 // Shrink TableView to lie within border. + + backgroundVisible: true + + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff + + style: TableViewStyle { + // Needed in order for rows to keep displaying rows after end of table entries. + backgroundColor: tableView.isLightColorScheme ? hifi.colors.tableBackgroundLight : hifi.colors.tableBackgroundDark + alternateBackgroundColor: tableView.isLightColorScheme ? hifi.colors.tableRowLightOdd : hifi.colors.tableRowDarkOdd + padding.top: headerVisible ? hifi.dimensions.tableHeaderHeight: 0 + } + + rowDelegate: Rectangle { + height: (styleData.selected && expandSelectedRow ? 1.8 : 1) * hifi.dimensions.tableRowHeight + color: styleData.selected + ? hifi.colors.primaryHighlight + : tableView.isLightColorScheme + ? (styleData.alternate ? hifi.colors.tableRowLightEven : hifi.colors.tableRowLightOdd) + : (styleData.alternate ? hifi.colors.tableRowDarkEven : hifi.colors.tableRowDarkOdd) + } +} diff --git a/interface/resources/qml/desktop/+android/Desktop.qml b/interface/resources/qml/desktop/+android/Desktop.qml new file mode 100644 index 0000000000..6a68f63d0a --- /dev/null +++ b/interface/resources/qml/desktop/+android/Desktop.qml @@ -0,0 +1,575 @@ +// +// Desktop.qml +// +// Created by Bradley Austin Davis on 15 Apr 2015 +// Copyright 2015 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.7 +import QtQuick.Controls 1.4 + +import "../dialogs" +import "../js/Utils.js" as Utils + +// This is our primary 'desktop' object to which all VR dialogs and windows are childed. +FocusScope { + id: desktop + objectName: "desktop" + anchors.fill: parent + + readonly property int invalid_position: -9999; + property rect recommendedRect: Qt.rect(0,0,0,0); + property var expectedChildren; + property bool repositionLocked: true + property bool hmdHandMouseActive: false + + onRepositionLockedChanged: { + if (!repositionLocked) { + d.handleSizeChanged(); + } + + } + + onHeightChanged: d.handleSizeChanged(); + + onWidthChanged: d.handleSizeChanged(); + + // Controls and windows can trigger this signal to ensure the desktop becomes visible + // when they're opened. + signal showDesktop(); + + // This is for JS/QML communication, which is unused in the Desktop, + // but not having this here results in spurious warnings about a + // missing signal + signal sendToScript(var message); + + // Allows QML/JS to find the desktop through the parent chain + property bool desktopRoot: true + + // The VR version of the primary menu + property var rootMenu: Menu { + id: rootMenuId + objectName: "rootMenu" + + property var exclusionGroups: ({}); + property Component exclusiveGroupMaker: Component { + ExclusiveGroup { + } + } + + function addExclusionGroup(qmlAction, exclusionGroup) { + + var exclusionGroupId = exclusionGroup.toString(); + if(!exclusionGroups[exclusionGroupId]) { + exclusionGroups[exclusionGroupId] = exclusiveGroupMaker.createObject(rootMenuId); + } + + qmlAction.exclusiveGroup = exclusionGroups[exclusionGroupId] + } + } + + // FIXME: Alpha gradients display as fuschia under QtQuick 2.5 on OSX/AMD + // because shaders are 4.2, and do not include #version declarations. + property bool gradientsSupported: Qt.platform.os != "osx" && !~GL.vendor.indexOf("ATI") + + readonly property alias zLevels: zLevels + QtObject { + id: zLevels; + readonly property real normal: 1 // make windows always appear higher than QML overlays and other non-window controls. + readonly property real top: 2000 + readonly property real modal: 4000 + readonly property real menu: 8000 + } + + QtObject { + id: d + + function handleSizeChanged() { + if (desktop.repositionLocked) { + return; + } + var oldRecommendedRect = recommendedRect; + var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect(); + var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y, + newRecommendedRectJS.width, + newRecommendedRectJS.height); + + var oldChildren = expectedChildren; + var newChildren = d.getRepositionChildren(); + if (oldRecommendedRect != Qt.rect(0,0,0,0) && oldRecommendedRect != Qt.rect(0,0,1,1) + && (oldRecommendedRect != newRecommendedRect + || oldChildren != newChildren) + ) { + expectedChildren = newChildren; + d.repositionAll(); + } + recommendedRect = newRecommendedRect; + } + + function findChild(item, name) { + for (var i = 0; i < item.children.length; ++i) { + if (item.children[i].objectName === name) { + return item.children[i]; + } + } + return null; + } + + function findParentMatching(item, predicate) { + while (item) { + if (predicate(item)) { + break; + } + item = item.parent; + } + return item; + } + + function findMatchingChildren(item, predicate) { + var results = []; + for (var i in item.children) { + var child = item.children[i]; + if (predicate(child)) { + results.push(child); + } + } + return results; + } + + function isTopLevelWindow(item) { + return item.topLevelWindow; + } + + function isAlwaysOnTopWindow(window) { + return window.alwaysOnTop; + } + + function isModalWindow(window) { + return window.modality !== Qt.NonModal; + } + + function getTopLevelWindows(predicate) { + return findMatchingChildren(desktop, function(child) { + return (isTopLevelWindow(child) && (!predicate || predicate(child))); + }); + } + + function getDesktopWindow(item) { + return findParentMatching(item, isTopLevelWindow) + } + + function fixupZOrder(windows, basis, topWindow) { + windows.sort(function(a, b){ return a.z - b.z; }); + + if ((topWindow.z >= basis) && (windows[windows.length - 1] === topWindow)) { + return; + } + + var lastZ = -1; + var lastTargetZ = basis - 1; + for (var i = 0; i < windows.length; ++i) { + var window = windows[i]; + if (!window.visible) { + continue + } + + if (topWindow && (topWindow === window)) { + continue + } + + if (window.z > lastZ) { + lastZ = window.z; + ++lastTargetZ; + } + if (DebugQML) { + console.log("Assigning z order " + lastTargetZ + " to " + window) + } + + window.z = lastTargetZ; + } + if (topWindow) { + ++lastTargetZ; + if (DebugQML) { + console.log("Assigning z order " + lastTargetZ + " to " + topWindow) + } + topWindow.z = lastTargetZ; + } + + return lastTargetZ; + } + + function raiseWindow(targetWindow) { + var predicate; + var zBasis; + if (isModalWindow(targetWindow)) { + predicate = isModalWindow; + zBasis = zLevels.modal + } else if (isAlwaysOnTopWindow(targetWindow)) { + predicate = function(window) { + return (isAlwaysOnTopWindow(window) && !isModalWindow(window)); + } + zBasis = zLevels.top + } else { + predicate = function(window) { + return (!isAlwaysOnTopWindow(window) && !isModalWindow(window)); + } + zBasis = zLevels.normal + } + + var windows = getTopLevelWindows(predicate); + fixupZOrder(windows, zBasis, targetWindow); + } + + Component.onCompleted: { + //offscreenWindow.activeFocusItemChanged.connect(onWindowFocusChanged); + focusHack.start(); + } + + function onWindowFocusChanged() { + //console.log("Focus item is " + offscreenWindow.activeFocusItem); + + // FIXME this needs more testing before it can go into production + // and I already cant produce any way to have a modal dialog lose focus + // to a non-modal one. + /* + var focusedWindow = getDesktopWindow(offscreenWindow.activeFocusItem); + + if (isModalWindow(focusedWindow)) { + return; + } + + // new focused window is not modal... check if there are any modal windows + var windows = getTopLevelWindows(isModalWindow); + if (0 === windows.length) { + return; + } + + // There are modal windows present, force focus back to the top-most modal window + windows.sort(function(a, b){ return a.z - b.z; }); + windows[windows.length - 1].focus = true; + */ + +// var focusedItem = offscreenWindow.activeFocusItem ; +// if (DebugQML && focusedItem) { +// var rect = desktop.mapFromItem(focusedItem, 0, 0, focusedItem.width, focusedItem.height); +// focusDebugger.x = rect.x; +// focusDebugger.y = rect.y; +// focusDebugger.width = rect.width +// focusDebugger.height = rect.height +// } + } + + function getRepositionChildren(predicate) { + return findMatchingChildren(desktop, function(child) { + return (child.shouldReposition === true && (!predicate || predicate(child))); + }); + } + + function repositionAll() { + if (desktop.repositionLocked) { + return; + } + + var oldRecommendedRect = recommendedRect; + var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height }; + var newRecommendedRect = Controller.getRecommendedHUDRect(); + var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height }; + var windows = d.getTopLevelWindows(); + for (var i = 0; i < windows.length; ++i) { + var targetWindow = windows[i]; + if (targetWindow.visible) { + repositionWindow(targetWindow, true, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions); + } + } + + // also reposition the other children that aren't top level windows but want to be repositioned + var otherChildren = d.getRepositionChildren(); + for (var i = 0; i < otherChildren.length; ++i) { + var child = otherChildren[i]; + repositionWindow(child, true, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions); + } + + } + } + + property bool pinned: false + property var hiddenChildren: [] + + function togglePinned() { + pinned = !pinned + } + + function isPointOnWindow(point) { + for (var i = 0; i < desktop.visibleChildren.length; i++) { + var child = desktop.visibleChildren[i]; + if (child.hasOwnProperty("modality")) { + var mappedPoint = mapToItem(child, point.x, point.y); + if (child.hasOwnProperty("frame")) { + var outLine = child.frame.children[2]; + var framePoint = outLine.mapFromGlobal(point.x, point.y); + if (outLine.contains(framePoint)) { + return true; + } + } + + if (child.contains(mappedPoint)) { + return true; + } + } + } + return false; + } + + function setPinned(newPinned) { + pinned = newPinned + } + + property real unpinnedAlpha: 1.0; + + Behavior on unpinnedAlpha { + NumberAnimation { + easing.type: Easing.Linear; + duration: 300 + } + } + + state: "NORMAL" + states: [ + State { + name: "NORMAL" + PropertyChanges { target: desktop; unpinnedAlpha: 1.0 } + }, + State { + name: "PINNED" + PropertyChanges { target: desktop; unpinnedAlpha: 0.0 } + } + ] + + transitions: [ + Transition { + NumberAnimation { properties: "unpinnedAlpha"; duration: 300 } + } + ] + + onPinnedChanged: { + if (pinned) { + d.raiseWindow(desktop); + desktop.focus = true; + desktop.forceActiveFocus(); + + // recalculate our non-pinned children + hiddenChildren = d.findMatchingChildren(desktop, function(child){ + return !d.isTopLevelWindow(child) && child.visible && !child.pinned; + }); + + hiddenChildren.forEach(function(child){ + child.opacity = Qt.binding(function(){ return desktop.unpinnedAlpha }); + }); + } + state = pinned ? "PINNED" : "NORMAL" + } + + onShowDesktop: pinned = false + + function raise(item) { + var targetWindow = d.getDesktopWindow(item); + if (!targetWindow) { + console.warn("Could not find top level window for " + item); + return; + } + + // Fix up the Z-order (takes into account if this is a modal window) + d.raiseWindow(targetWindow); + var setFocus = true; + if (!d.isModalWindow(targetWindow)) { + var modalWindows = d.getTopLevelWindows(d.isModalWindow); + if (modalWindows.length) { + setFocus = false; + } + } + + if (setFocus) { + targetWindow.focus = true; + } + + showDesktop(); + } + + function ensureTitleBarVisible(targetWindow) { + // Reposition window to ensure that title bar is vertically inside window. + if (targetWindow.frame && targetWindow.frame.decoration) { + var topMargin = -targetWindow.frame.decoration.anchors.topMargin; // Frame's topMargin is a negative value. + targetWindow.y = Math.max(targetWindow.y, topMargin); + } + } + + function centerOnVisible(item) { + var targetWindow = d.getDesktopWindow(item); + if (!targetWindow) { + console.warn("Could not find top level window for " + item); + return; + } + + if (typeof Controller === "undefined") { + console.warn("Controller not yet available... can't center"); + return; + } + + var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect(); + var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y, + newRecommendedRectJS.width, + newRecommendedRectJS.height); + var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height }; + var newX = newRecommendedRect.x + ((newRecommendedRect.width - targetWindow.width) / 2); + var newY = newRecommendedRect.y + ((newRecommendedRect.height - targetWindow.height) / 2); + targetWindow.x = newX; + targetWindow.y = newY; + + ensureTitleBarVisible(targetWindow); + + // If we've noticed that our recommended desktop rect has changed, record that change here. + if (recommendedRect != newRecommendedRect) { + recommendedRect = newRecommendedRect; + } + } + + function repositionOnVisible(item) { + var targetWindow = d.getDesktopWindow(item); + if (!targetWindow) { + console.warn("Could not find top level window for " + item); + return; + } + + if (typeof Controller === "undefined") { + console.warn("Controller not yet available... can't reposition targetWindow:" + targetWindow); + return; + } + + var oldRecommendedRect = recommendedRect; + var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height }; + var newRecommendedRect = Controller.getRecommendedHUDRect(); + var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height }; + repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions); + } + + function repositionWindow(targetWindow, forceReposition, + oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions) { + + if (desktop.width === 0 || desktop.height === 0) { + return; + } + + if (!targetWindow) { + console.warn("Could not find top level window for " + item); + return; + } + + var recommended = Controller.getRecommendedHUDRect(); + var maxX = recommended.x + recommended.width; + var maxY = recommended.y + recommended.height; + var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y); + + // if we asked to force reposition, or if the window is completely outside of the recommended rectangle, reposition it + if (forceReposition || (targetWindow.x > maxX || (targetWindow.x + targetWindow.width) < recommended.x) || + (targetWindow.y > maxY || (targetWindow.y + targetWindow.height) < recommended.y)) { + newPosition.x = -1 + newPosition.y = -1 + } + + if (newPosition.x === -1 && newPosition.y === -1) { + var originRelativeX = (targetWindow.x - oldRecommendedRect.x); + var originRelativeY = (targetWindow.y - oldRecommendedRect.y); + if (isNaN(originRelativeX)) { + originRelativeX = 0; + } + if (isNaN(originRelativeY)) { + originRelativeY = 0; + } + var fractionX = Utils.clamp(originRelativeX / oldRecommendedDimmensions.x, 0, 1); + var fractionY = Utils.clamp(originRelativeY / oldRecommendedDimmensions.y, 0, 1); + var newX = (fractionX * newRecommendedDimmensions.x) + newRecommendedRect.x; + var newY = (fractionY * newRecommendedDimmensions.y) + newRecommendedRect.y; + newPosition = Qt.vector2d(newX, newY); + } + targetWindow.x = newPosition.x; + targetWindow.y = newPosition.y; + + ensureTitleBarVisible(targetWindow); + } + + Component { id: messageDialogBuilder; MessageDialog { } } + function messageBox(properties) { + return messageDialogBuilder.createObject(desktop, properties); + } + + Component { id: inputDialogBuilder; QueryDialog { } } + function inputDialog(properties) { + return inputDialogBuilder.createObject(desktop, properties); + } + + Component { id: customInputDialogBuilder; CustomQueryDialog { } } + function customInputDialog(properties) { + return customInputDialogBuilder.createObject(desktop, properties); + } + + Component { id: fileDialogBuilder; FileDialog { } } + function fileDialog(properties) { + return fileDialogBuilder.createObject(desktop, properties); + } + + Component { id: assetDialogBuilder; AssetDialog { } } + function assetDialog(properties) { + return assetDialogBuilder.createObject(desktop, properties); + } + + function unfocusWindows() { + // First find the active focus item, and unfocus it, all the way + // up the parent chain to the window + var currentFocus = offscreenWindow.activeFocusItem; + var targetWindow = d.getDesktopWindow(currentFocus); + while (currentFocus) { + if (currentFocus === targetWindow) { + break; + } + currentFocus.focus = false; + currentFocus = currentFocus.parent; + } + + // Unfocus all windows + var windows = d.getTopLevelWindows(); + for (var i = 0; i < windows.length; ++i) { + windows[i].focus = false; + } + + // For the desktop to have active focus + desktop.focus = true; + desktop.forceActiveFocus(); + } + + function openBrowserWindow(request, profile) { + var component = Qt.createComponent("../Browser.qml"); + var newWindow = component.createObject(desktop); + newWindow.webView.profile = profile; + request.openIn(newWindow.webView); + } + + FocusHack { id: focusHack; } + + Rectangle { + id: focusDebugger; + objectName: "focusDebugger" + z: 9999; visible: false; color: "red" + ColorAnimation on color { from: "#7fffff00"; to: "#7f0000ff"; duration: 1000; loops: 9999 } + } + + Action { + text: "Toggle Focus Debugger" + shortcut: "Ctrl+Shift+F" + enabled: DebugQML + onTriggered: focusDebugger.visible = !focusDebugger.visible + } + +} diff --git a/interface/resources/qml/dialogs/+android/CustomQueryDialog.qml b/interface/resources/qml/dialogs/+android/CustomQueryDialog.qml new file mode 100644 index 0000000000..b1b6de4644 --- /dev/null +++ b/interface/resources/qml/dialogs/+android/CustomQueryDialog.qml @@ -0,0 +1,338 @@ +// +// CustomQueryDialog.qml +// +// Created by Zander Otavka on 7/14/16 +// Copyright 2016 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.7; +import QtQuick.Dialogs 1.2 as OriginalDialogs; +import QtQuick.Controls 1.4; + +import "../controls-uit"; +import "../styles-uit"; +import "../windows"; + +ModalWindow { + id: root; + HifiConstants { id: hifi; } + implicitWidth: 640; + implicitHeight: 320; + visible: true; + keyboardOverride: true // Disable ModalWindow's keyboard. + + signal selected(var result); + signal canceled(); + + property int icon: hifi.icons.none; + property string iconText: ""; + property int iconSize: 35; + onIconChanged: updateIcon(); + + property var textInput; + property var comboBox; + property var checkBox; + onTextInputChanged: { + if (textInput && textInput.text !== undefined) { + textField.text = textInput.text; + } + } + onComboBoxChanged: { + if (comboBox && comboBox.index !== undefined) { + comboBoxField.currentIndex = comboBox.index; + } + } + onCheckBoxChanged: { + if (checkBox && checkBox.checked !== undefined) { + checkBoxField.checked = checkBox.checked; + } + } + + property bool keyboardEnabled: false + property bool keyboardRaised: false + property bool punctuationMode: false + onKeyboardRaisedChanged: d.resize(); + + property var warning: ""; + property var result; + + property var implicitCheckState: null; + + property int titleWidth: 0; + onTitleWidthChanged: d.resize(); + + function updateIcon() { + if (!root) { + return; + } + iconText = hifi.glyphForIcon(root.icon); + } + + function updateCheckbox() { + if (checkBox.disableForItems) { + var currentItemInDisableList = false; + for (var i in checkBox.disableForItems) { + if (comboBoxField.currentIndex === checkBox.disableForItems[i]) { + currentItemInDisableList = true; + break; + } + } + + if (currentItemInDisableList) { + checkBoxField.enabled = false; + if (checkBox.checkStateOnDisable !== null && checkBox.checkStateOnDisable !== undefined) { + root.implicitCheckState = checkBoxField.checked; + checkBoxField.checked = checkBox.checkStateOnDisable; + } + root.warning = checkBox.warningOnDisable; + } else { + checkBoxField.enabled = true; + if (root.implicitCheckState !== null) { + checkBoxField.checked = root.implicitCheckState; + root.implicitCheckState = null; + } + root.warning = ""; + } + } + } + + Item { + clip: true; + width: pane.width; + height: pane.height; + anchors.margins: 0; + + QtObject { + id: d; + readonly property int minWidth: 480 + readonly property int maxWdith: 1280 + readonly property int minHeight: 120 + readonly property int maxHeight: 720 + + function resize() { + var targetWidth = Math.max(titleWidth, pane.width); + var targetHeight = (textField.visible ? textField.controlHeight + hifi.dimensions.contentSpacing.y : 0) + + (extraInputs.visible ? extraInputs.height + hifi.dimensions.contentSpacing.y : 0) + + (buttons.height + 3 * hifi.dimensions.contentSpacing.y) + + ((keyboardEnabled && keyboardRaised) ? (keyboard.raisedHeight + hifi.dimensions.contentSpacing.y) : 0); + + root.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWdith) ? d.maxWidth : targetWidth); + root.height = (targetHeight < d.minHeight) ? d.minHeight : ((targetHeight > d.maxHeight) ? + d.maxHeight : targetHeight); + } + } + + Item { + anchors { + top: parent.top; + bottom: extraInputs.visible ? extraInputs.top : buttons.top; + left: parent.left; + right: parent.right; + margins: 0; + } + + // FIXME make a text field type that can be bound to a history for autocompletion + TextField { + id: textField; + label: root.textInput.label; + focus: root.textInput ? true : false; + visible: root.textInput ? true : false; + anchors { + left: parent.left; + right: parent.right; + bottom: keyboard.top; + bottomMargin: hifi.dimensions.contentSpacing.y; + } + } + + Keyboard { + id: keyboard + raised: keyboardEnabled && keyboardRaised + numeric: punctuationMode + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + bottomMargin: raised ? hifi.dimensions.contentSpacing.y : 0 + } + } + } + + Item { + id: extraInputs; + visible: Boolean(root.checkBox || root.comboBox); + anchors { + left: parent.left; + right: parent.right; + bottom: buttons.top; + bottomMargin: hifi.dimensions.contentSpacing.y; + } + height: comboBoxField.controlHeight; + onHeightChanged: d.resize(); + onWidthChanged: d.resize(); + + CheckBox { + id: checkBoxField; + text: root.checkBox.label; + focus: Boolean(root.checkBox); + visible: Boolean(root.checkBox); + anchors { + left: parent.left; + bottom: parent.bottom; + leftMargin: 6; // Magic number to align with warning icon + bottomMargin: 6; + } + } + + ComboBox { + id: comboBoxField; + label: root.comboBox.label; + focus: Boolean(root.comboBox); + visible: Boolean(root.comboBox); + Binding on x { + when: comboBoxField.visible + value: !checkBoxField.visible ? buttons.x : acceptButton.x + } + + Binding on width { + when: comboBoxField.visible + value: !checkBoxField.visible ? buttons.width : buttons.width - acceptButton.x + } + anchors { + right: parent.right; + bottom: parent.bottom; + } + model: root.comboBox ? root.comboBox.items : []; + onAccepted: { + updateCheckbox(); + focus = true; + } + } + } + + Row { + id: buttons; + focus: true; + spacing: hifi.dimensions.contentSpacing.x; + layoutDirection: Qt.RightToLeft; + onHeightChanged: d.resize(); + onWidthChanged: { + d.resize(); + resizeWarningText(); + } + + anchors { + bottom: parent.bottom; + left: parent.left; + right: parent.right; + bottomMargin: hifi.dimensions.contentSpacing.y; + } + + function resizeWarningText() { + var rowWidth = buttons.width; + var buttonsWidth = acceptButton.width + cancelButton.width + hifi.dimensions.contentSpacing.x * 2; + var warningIconWidth = warningIcon.width + hifi.dimensions.contentSpacing.x; + warningText.width = rowWidth - buttonsWidth - warningIconWidth; + } + + Button { + id: cancelButton; + action: cancelAction; + } + + Button { + id: acceptButton; + action: acceptAction; + } + + Text { + id: warningText; + visible: Boolean(root.warning); + text: root.warning; + wrapMode: Text.WordWrap; + font.italic: true; + maximumLineCount: 2; + } + + HiFiGlyphs { + id: warningIcon; + visible: Boolean(root.warning); + text: hifi.glyphs.alert; + size: hifi.dimensions.controlLineHeight; + width: 20 // Line up with checkbox. + } + } + + Action { + id: cancelAction; + text: qsTr("Cancel"); + shortcut: "Esc"; + onTriggered: { + root.result = null; + root.canceled(); + // FIXME we are leaking memory to avoid a crash + // root.destroy(); + + root.disableFade = true + visible = false; + } + } + + Action { + id: acceptAction; + text: qsTr("Add"); + shortcut: "Return" + onTriggered: { + var result = {}; + if (textInput) { + result.textInput = textField.text; + } + if (comboBox) { + result.comboBox = comboBoxField.currentIndex; + result.comboBoxText = comboBoxField.currentText; + } + if (checkBox) { + result.checkBox = checkBoxField.enabled ? checkBoxField.checked : null; + } + root.result = JSON.stringify(result); + root.selected(root.result); + // FIXME we are leaking memory to avoid a crash + // root.destroy(); + + root.disableFade = true + visible = false; + } + } + } + + Keys.onPressed: { + if (!visible) { + return; + } + + switch (event.key) { + case Qt.Key_Escape: + case Qt.Key_Back: + cancelAction.trigger(); + event.accepted = true; + break; + + case Qt.Key_Return: + case Qt.Key_Enter: + acceptAction.trigger(); + event.accepted = true; + break; + } + } + + Component.onCompleted: { + keyboardEnabled = HMD.active; + updateIcon(); + updateCheckbox(); + d.resize(); + textField.forceActiveFocus(); + } +} diff --git a/interface/resources/qml/dialogs/+android/FileDialog.qml b/interface/resources/qml/dialogs/+android/FileDialog.qml new file mode 100644 index 0000000000..548ab453a7 --- /dev/null +++ b/interface/resources/qml/dialogs/+android/FileDialog.qml @@ -0,0 +1,840 @@ +// +// FileDialog.qml +// +// Created by Bradley Austin Davis on 14 Jan 2016 +// Copyright 2015 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.7 +import Qt.labs.folderlistmodel 2.1 +import Qt.labs.settings 1.0 +import QtQuick.Dialogs 1.2 as OriginalDialogs +import QtQuick.Controls 1.4 + +import ".." +import "../controls-uit" +import "../styles-uit" +import "../windows" + +import "fileDialog" + +//FIXME implement shortcuts for favorite location +ModalWindow { + id: root + resizable: true + implicitWidth: 480 + implicitHeight: 360 + (fileDialogItem.keyboardEnabled && fileDialogItem.keyboardRaised ? keyboard.raisedHeight + hifi.dimensions.contentSpacing.y : 0) + + minSize: Qt.vector2d(360, 240) + draggable: true + + HifiConstants { id: hifi } + + property var filesModel: ListModel { } + + Settings { + category: "FileDialog" + property alias width: root.width + property alias height: root.height + property alias x: root.x + property alias y: root.y + } + + + // Set from OffscreenUi::getOpenFile() + property alias caption: root.title; + // Set from OffscreenUi::getOpenFile() + property alias dir: fileTableModel.folder; + // Set from OffscreenUi::getOpenFile() + property alias filter: selectionType.filtersString; + // Set from OffscreenUi::getOpenFile() + property int options; // <-- FIXME unused + + property string iconText: root.title !== "" ? hifi.glyphs.scriptUpload : "" + property int iconSize: 40 + + property bool selectDirectory: false; + property bool showHidden: false; + // FIXME implement + property bool multiSelect: false; + property bool saveDialog: false; + property var helper: fileDialogHelper + property alias model: fileTableView.model + property var drives: helper.drives() + + property int titleWidth: 0 + + signal selectedFile(var file); + signal canceled(); + signal selected(int button); + function click(button) { + clickedButton = button; + selected(button); + destroy(); + } + + property int clickedButton: OriginalDialogs.StandardButton.NoButton; + + Component.onCompleted: { + console.log("Helper " + helper + " drives " + drives); + + fileDialogItem.keyboardEnabled = HMD.active; + + // HACK: The following lines force the model to initialize properly such that the go-up button + // works properly from the initial screen. + var initialFolder = folderListModel.folder; + fileTableModel.folder = helper.pathToUrl(drives[0]); + fileTableModel.folder = initialFolder; + + iconText = root.title !== "" ? hifi.glyphs.scriptUpload : ""; + + // Clear selection when click on external frame. + frameClicked.connect(function() { d.clearSelection(); }); + + if (selectDirectory) { + currentSelection.text = d.capitalizeDrive(helper.urlToPath(initialFolder)); + d.currentSelectionIsFolder = true; + d.currentSelectionUrl = initialFolder; + } + + helper.contentsChanged.connect(function() { + if (folderListModel) { + // Make folderListModel refresh. + var save = folderListModel.folder; + folderListModel.folder = ""; + folderListModel.folder = save; + } + }); + + focusTimer.start(); + } + + Timer { + id: focusTimer + interval: 10 + running: false + repeat: false + onTriggered: { + fileTableView.contentItem.forceActiveFocus(); + } + } + + Item { + id: fileDialogItem + clip: true + width: pane.width + height: pane.height + anchors.margins: 0 + + property bool keyboardEnabled: false + property bool keyboardRaised: false + property bool punctuationMode: false + + MouseArea { + // Clear selection when click on internal unused area. + anchors.fill: parent + drag.target: root + onClicked: { + d.clearSelection(); + // Defocus text field so that the keyboard gets hidden. + // Clicking also breaks keyboard navigation apart from backtabbing to cancel + frame.forceActiveFocus(); + } + } + + Row { + id: navControls + anchors { + top: parent.top + topMargin: hifi.dimensions.contentMargin.y + left: parent.left + } + spacing: hifi.dimensions.contentSpacing.x + + GlyphButton { + id: upButton + glyph: hifi.glyphs.levelUp + width: height + size: 30 + enabled: fileTableModel.parentFolder && fileTableModel.parentFolder !== "" + onClicked: d.navigateUp(); + Keys.onReturnPressed: { d.navigateUp(); } + KeyNavigation.tab: homeButton + KeyNavigation.backtab: upButton + KeyNavigation.left: upButton + KeyNavigation.right: homeButton + } + + GlyphButton { + id: homeButton + property var destination: helper.home(); + glyph: hifi.glyphs.home + size: 28 + width: height + enabled: d.homeDestination ? true : false + onClicked: d.navigateHome(); + Keys.onReturnPressed: { d.navigateHome(); } + KeyNavigation.tab: fileTableView.contentItem + KeyNavigation.backtab: upButton + KeyNavigation.left: upButton + } + } + + ComboBox { + id: pathSelector + anchors { + top: parent.top + topMargin: hifi.dimensions.contentMargin.y + left: navControls.right + leftMargin: hifi.dimensions.contentSpacing.x + right: parent.right + } + + property var lastValidFolder: helper.urlToPath(fileTableModel.folder) + + function calculatePathChoices(folder) { + var folders = folder.split("/"), + choices = [], + i, length; + + if (folders[folders.length - 1] === "") { + folders.pop(); + } + + choices.push(folders[0]); + + for (i = 1, length = folders.length; i < length; i++) { + choices.push(choices[i - 1] + "/" + folders[i]); + } + + if (folders[0] === "") { + // Special handling for OSX root dir. + choices[0] = "/"; + } + + choices.reverse(); + + if (drives && drives.length > 1) { + choices.push("This PC"); + } + + if (choices.length > 0) { + pathSelector.model = choices; + } + } + + onLastValidFolderChanged: { + var folder = d.capitalizeDrive(lastValidFolder); + calculatePathChoices(folder); + } + + onCurrentTextChanged: { + var folder = currentText; + + if (/^[a-zA-z]:$/.test(folder)) { + folder = "file:///" + folder + "/"; + } else if (folder === "This PC") { + folder = "file:///"; + } else { + folder = helper.pathToUrl(folder); + } + + if (helper.urlToPath(folder).toLowerCase() !== helper.urlToPath(fileTableModel.folder).toLowerCase()) { + if (root.selectDirectory) { + currentSelection.text = currentText !== "This PC" ? currentText : ""; + d.currentSelectionUrl = helper.pathToUrl(currentText); + } + fileTableModel.folder = folder; + } + } + + KeyNavigation.up: fileTableView.contentItem + KeyNavigation.down: fileTableView.contentItem + KeyNavigation.tab: fileTableView.contentItem + KeyNavigation.backtab: fileTableView.contentItem + KeyNavigation.left: fileTableView.contentItem + KeyNavigation.right: fileTableView.contentItem + } + + QtObject { + id: d + property var currentSelectionUrl; + readonly property string currentSelectionPath: helper.urlToPath(currentSelectionUrl); + property bool currentSelectionIsFolder; + property var backStack: [] + property var tableViewConnection: Connections { target: fileTableView; onCurrentRowChanged: d.update(); } + property var modelConnection: Connections { target: fileTableModel; onFolderChanged: d.update(); } + property var homeDestination: helper.home(); + + function capitalizeDrive(path) { + // Consistently capitalize drive letter for Windows. + if (/[a-zA-Z]:/.test(path)) { + return path.charAt(0).toUpperCase() + path.slice(1); + } + return path; + } + + function update() { + var row = fileTableView.currentRow; + + if (row === -1) { + if (!root.selectDirectory) { + currentSelection.text = ""; + currentSelectionIsFolder = false; + } + return; + } + + currentSelectionUrl = helper.pathToUrl(fileTableView.model.get(row).filePath); + currentSelectionIsFolder = fileTableView.model !== filesModel ? + fileTableView.model.isFolder(row) : + fileTableModel.isFolder(row); + if (root.selectDirectory || !currentSelectionIsFolder) { + currentSelection.text = capitalizeDrive(helper.urlToPath(currentSelectionUrl)); + } else { + currentSelection.text = ""; + } + } + + function navigateUp() { + if (fileTableModel.parentFolder && fileTableModel.parentFolder !== "") { + fileTableModel.folder = fileTableModel.parentFolder; + return true; + } + } + + function navigateHome() { + fileTableModel.folder = homeDestination; + return true; + } + + function clearSelection() { + fileTableView.selection.clear(); + fileTableView.currentRow = -1; + update(); + } + } + + FolderListModel { + id: folderListModel + nameFilters: selectionType.currentFilter + showDirsFirst: true + showDotAndDotDot: false + showFiles: !root.selectDirectory + Component.onCompleted: { + showFiles = !root.selectDirectory + } + + onFolderChanged: { + fileTableModel.update(); // Update once the data from the folder change is available. + } + + function getItem(index, field) { + return get(index, field); + } + } + + ListModel { + // Emulates FolderListModel but contains drive data. + id: driveListModel + + property int count: 1 + + Component.onCompleted: initialize(); + + function initialize() { + var drive, + i; + + count = drives.length; + + for (i = 0; i < count; i++) { + drive = drives[i].slice(0, -1); // Remove trailing "/". + append({ + fileName: drive, + fileModified: new Date(0), + fileSize: 0, + filePath: drive + "/", + fileIsDir: true, + fileNameSort: drive.toLowerCase() + }); + } + } + + function getItem(index, field) { + return get(index)[field]; + } + } + + Component { + id: filesModelBuilder + ListModel { } + } + + QtObject { + id: fileTableModel + + // FolderListModel has a couple of problems: + // 1) Files and directories sort case-sensitively: https://bugreports.qt.io/browse/QTBUG-48757 + // 2) Cannot browse up to the "computer" level to view Windows drives: https://bugreports.qt.io/browse/QTBUG-42901 + // + // To solve these problems an intermediary ListModel is used that implements proper sorting and can be populated with + // drive information when viewing at the computer level. + + property var folder + property int sortOrder: Qt.AscendingOrder + property int sortColumn: 0 + property var model: folderListModel + property string parentFolder: calculateParentFolder(); + + readonly property string rootFolder: "file:///" + + function calculateParentFolder() { + if (model === folderListModel) { + if (folderListModel.parentFolder.toString() === "" && driveListModel.count > 1) { + return rootFolder; + } else { + return folderListModel.parentFolder; + } + } else { + return ""; + } + } + + onFolderChanged: { + if (folder === rootFolder) { + model = driveListModel; + helper.monitorDirectory(""); + update(); + } else { + var needsUpdate = model === driveListModel && folder === folderListModel.folder; + + model = folderListModel; + folderListModel.folder = folder; + helper.monitorDirectory(helper.urlToPath(folder)); + + if (needsUpdate) { + update(); + } + } + } + + function isFolder(row) { + if (row === -1) { + return false; + } + return filesModel.get(row).fileIsDir; + } + + function get(row) { + return filesModel.get(row) + } + + function update() { + var dataFields = ["fileName", "fileModified", "fileSize"], + sortFields = ["fileNameSort", "fileModified", "fileSize"], + dataField = dataFields[sortColumn], + sortField = sortFields[sortColumn], + sortValue, + fileName, + fileIsDir, + comparisonFunction, + lower, + middle, + upper, + rows = 0, + i; + + var newFilesModel = filesModelBuilder.createObject(root); + + comparisonFunction = sortOrder === Qt.AscendingOrder + ? function(a, b) { return a < b; } + : function(a, b) { return a > b; } + + for (i = 0; i < model.count; i++) { + fileName = model.getItem(i, "fileName"); + fileIsDir = model.getItem(i, "fileIsDir"); + + sortValue = model.getItem(i, dataField); + if (dataField === "fileName") { + // Directories first by prefixing a "*". + // Case-insensitive. + sortValue = (fileIsDir ? "*" : "") + sortValue.toLowerCase(); + } + + lower = 0; + upper = rows; + while (lower < upper) { + middle = Math.floor((lower + upper) / 2); + var lessThan; + if (comparisonFunction(sortValue, newFilesModel.get(middle)[sortField])) { + lessThan = true; + upper = middle; + } else { + lessThan = false; + lower = middle + 1; + } + } + + newFilesModel.insert(lower, { + fileName: fileName, + fileModified: (fileIsDir ? new Date(0) : model.getItem(i, "fileModified")), + fileSize: model.getItem(i, "fileSize"), + filePath: model.getItem(i, "filePath"), + fileIsDir: fileIsDir, + fileNameSort: (fileIsDir ? "*" : "") + fileName.toLowerCase() + }); + + rows++; + } + filesModel = newFilesModel; + + d.clearSelection(); + } + } + + Table { + id: fileTableView + colorScheme: hifi.colorSchemes.light + anchors { + top: navControls.bottom + topMargin: hifi.dimensions.contentSpacing.y + left: parent.left + right: parent.right + bottom: currentSelection.top + bottomMargin: hifi.dimensions.contentSpacing.y + currentSelection.controlHeight - currentSelection.height + } + headerVisible: !selectDirectory + onDoubleClicked: navigateToRow(row); + Keys.onReturnPressed: navigateToCurrentRow(); + Keys.onEnterPressed: navigateToCurrentRow(); + + sortIndicatorColumn: 0 + sortIndicatorOrder: Qt.AscendingOrder + sortIndicatorVisible: true + + model: filesModel + + function updateSort() { + fileTableModel.sortOrder = sortIndicatorOrder; + fileTableModel.sortColumn = sortIndicatorColumn; + fileTableModel.update(); + } + + onSortIndicatorColumnChanged: { updateSort(); } + + onSortIndicatorOrderChanged: { updateSort(); } + + itemDelegate: Item { + clip: true + + FiraSansSemiBold { + text: getText(); + elide: styleData.elideMode + anchors { + left: parent.left + leftMargin: hifi.dimensions.tablePadding + right: parent.right + rightMargin: hifi.dimensions.tablePadding + verticalCenter: parent.verticalCenter + } + size: hifi.fontSizes.tableText + color: hifi.colors.baseGrayHighlight + font.family: (styleData.row !== -1 && fileTableView.model.get(styleData.row).fileIsDir) + ? "Fira Sans SemiBold" : "Fira Sans" + + function getText() { + if (styleData.row === -1) { + return styleData.value; + } + + switch (styleData.column) { + case 1: return fileTableView.model.get(styleData.row).fileIsDir ? "" : styleData.value; + case 2: return fileTableView.model.get(styleData.row).fileIsDir ? "" : formatSize(styleData.value); + default: return styleData.value; + } + } + function formatSize(size) { + var suffixes = [ "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" ]; + var suffixIndex = 0 + while ((size / 1024.0) > 1.1) { + size /= 1024.0; + ++suffixIndex; + } + + size = Math.round(size*1000)/1000; + size = size.toLocaleString() + + return size + " " + suffixes[suffixIndex]; + } + } + } + + TableViewColumn { + id: fileNameColumn + role: "fileName" + title: "Name" + width: (selectDirectory ? 1.0 : 0.5) * fileTableView.width + movable: false + resizable: true + } + TableViewColumn { + id: fileModifiedColumn + role: "fileModified" + title: "Date" + width: 0.3 * fileTableView.width + movable: false + resizable: true + visible: !selectDirectory + } + TableViewColumn { + role: "fileSize" + title: "Size" + width: fileTableView.width - fileNameColumn.width - fileModifiedColumn.width + movable: false + resizable: true + visible: !selectDirectory + } + + function navigateToRow(row) { + currentRow = row; + navigateToCurrentRow(); + } + + function navigateToCurrentRow() { + var currentModel = fileTableView.model !== filesModel ? fileTableView.model : fileTableModel + var row = fileTableView.currentRow + var isFolder = currentModel.isFolder(row); + var file = currentModel.get(row).filePath; + if (isFolder) { + currentModel.folder = helper.pathToUrl(file); + } else { + okAction.trigger(); + } + } + + property string prefix: "" + + function addToPrefix(event) { + if (!event.text || event.text === "") { + return false; + } + var newPrefix = prefix + event.text.toLowerCase(); + var matchedIndex = -1; + for (var i = 0; i < model.count; ++i) { + var name = model !== filesModel ? model.get(i).fileName.toLowerCase() : + filesModel.get(i).fileName.toLowerCase(); + if (0 === name.indexOf(newPrefix)) { + matchedIndex = i; + break; + } + } + + if (matchedIndex !== -1) { + fileTableView.selection.clear(); + fileTableView.selection.select(matchedIndex); + fileTableView.currentRow = matchedIndex; + fileTableView.prefix = newPrefix; + } + prefixClearTimer.restart(); + return true; + } + + Timer { + id: prefixClearTimer + interval: 1000 + repeat: false + running: false + onTriggered: fileTableView.prefix = ""; + } + + Keys.onPressed: { + switch (event.key) { + case Qt.Key_Backspace: + case Qt.Key_Tab: + case Qt.Key_Backtab: + event.accepted = false; + break; + case Qt.Key_Escape: + event.accepted = true; + root.click(OriginalDialogs.StandardButton.Cancel); + break; + default: + if (addToPrefix(event)) { + event.accepted = true + } else { + event.accepted = false; + } + break; + } + } + + KeyNavigation.tab: root.saveDialog ? currentSelection : openButton + } + + TextField { + id: currentSelection + label: selectDirectory ? "Directory:" : "File name:" + anchors { + left: parent.left + right: selectionType.visible ? selectionType.left: parent.right + rightMargin: selectionType.visible ? hifi.dimensions.contentSpacing.x : 0 + bottom: keyboard.top + bottomMargin: hifi.dimensions.contentSpacing.y + } + readOnly: !root.saveDialog + activeFocusOnTab: !readOnly + onActiveFocusChanged: if (activeFocus) { selectAll(); } + onAccepted: okAction.trigger(); + KeyNavigation.up: fileTableView.contentItem + KeyNavigation.down: openButton + KeyNavigation.tab: openButton + KeyNavigation.backtab: fileTableView.contentItem + } + + FileTypeSelection { + id: selectionType + anchors { + top: currentSelection.top + left: buttonRow.left + right: parent.right + } + visible: !selectDirectory && filtersCount > 1 + } + + Keyboard { + id: keyboard + raised: parent.keyboardEnabled && parent.keyboardRaised + numeric: parent.punctuationMode + anchors { + left: parent.left + right: parent.right + bottom: buttonRow.top + bottomMargin: visible ? hifi.dimensions.contentSpacing.y : 0 + } + } + + Row { + id: buttonRow + anchors { + right: parent.right + bottom: parent.bottom + } + spacing: hifi.dimensions.contentSpacing.y + + Button { + id: openButton + color: hifi.buttons.blue + action: okAction + Keys.onReturnPressed: okAction.trigger() + KeyNavigation.right: cancelButton + KeyNavigation.up: root.saveDialog ? currentSelection : fileTableView.contentItem + KeyNavigation.tab: cancelButton + } + + Button { + id: cancelButton + action: cancelAction + Keys.onReturnPressed: { cancelAction.trigger() } + KeyNavigation.left: openButton + KeyNavigation.up: root.saveDialog ? currentSelection : fileTableView.contentItem + KeyNavigation.backtab: openButton + } + } + + Action { + id: okAction + text: currentSelection.text ? (root.selectDirectory && fileTableView.currentRow === -1 ? "Choose" : (root.saveDialog ? "Save" : "Open")) : "Open" + enabled: currentSelection.text || !root.selectDirectory && d.currentSelectionIsFolder ? true : false + onTriggered: { + if (!root.selectDirectory && !d.currentSelectionIsFolder + || root.selectDirectory && fileTableView.currentRow === -1) { + okActionTimer.start(); + } else { + fileTableView.navigateToCurrentRow(); + } + } + } + + Timer { + id: okActionTimer + interval: 50 + running: false + repeat: false + onTriggered: { + if (!root.saveDialog) { + selectedFile(d.currentSelectionUrl); + root.destroy() + return; + } + + // Handle the ambiguity between different cases + // * typed name (with or without extension) + // * full path vs relative vs filename only + var selection = helper.saveHelper(currentSelection.text, root.dir, selectionType.currentFilter); + + if (!selection) { + desktop.messageBox({ icon: OriginalDialogs.StandardIcon.Warning, text: "Unable to parse selection" }) + return; + } + + if (helper.urlIsDir(selection)) { + root.dir = selection; + currentSelection.text = ""; + return; + } + + // Check if the file is a valid target + if (!helper.urlIsWritable(selection)) { + desktop.messageBox({ + icon: OriginalDialogs.StandardIcon.Warning, + text: "Unable to write to location " + selection + }) + return; + } + + if (helper.urlExists(selection)) { + var messageBox = desktop.messageBox({ + icon: OriginalDialogs.StandardIcon.Question, + buttons: OriginalDialogs.StandardButton.Yes | OriginalDialogs.StandardButton.No, + text: "Do you wish to overwrite " + selection + "?", + }); + var result = messageBox.exec(); + if (OriginalDialogs.StandardButton.Yes !== result) { + return; + } + } + + console.log("Selecting " + selection) + selectedFile(selection); + root.destroy(); + } + } + + Action { + id: cancelAction + text: "Cancel" + onTriggered: { canceled(); root.shown = false; } + } + } + + Keys.onPressed: { + switch (event.key) { + case Qt.Key_Backspace: + event.accepted = d.navigateUp(); + break; + + case Qt.Key_Home: + event.accepted = d.navigateHome(); + break; + + case Qt.Key_Escape: + event.accepted = true; + root.click(OriginalDialogs.StandardButton.Cancel); + break; + } + } +} diff --git a/interface/resources/qml/dialogs/+android/QueryDialog.qml b/interface/resources/qml/dialogs/+android/QueryDialog.qml new file mode 100644 index 0000000000..aec6d8a286 --- /dev/null +++ b/interface/resources/qml/dialogs/+android/QueryDialog.qml @@ -0,0 +1,231 @@ +// +// QueryDialog.qml +// +// Created by Bradley Austin Davis on 22 Jan 2016 +// Copyright 2015 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.7 +import QtQuick.Controls 1.4 + +import "../controls-uit" +import "../styles-uit" +import "../windows" + +ModalWindow { + id: root + HifiConstants { id: hifi } + implicitWidth: 640 + implicitHeight: 320 + visible: true + keyboardOverride: true // Disable ModalWindow's keyboard. + + signal selected(var result); + signal canceled(); + + property int icon: hifi.icons.none + property string iconText: "" + property int iconSize: 35 + onIconChanged: updateIcon(); + + property var items; + property string label + property var result; + property alias current: textResult.text + + // For text boxes + property alias placeholderText: textResult.placeholderText + + // For combo boxes + property bool editable: true; + + property int titleWidth: 0 + onTitleWidthChanged: d.resize(); + + property bool keyboardEnabled: false + property bool keyboardRaised: false + property bool punctuationMode: false + + onKeyboardRaisedChanged: d.resize(); + + function updateIcon() { + if (!root) { + return; + } + iconText = hifi.glyphForIcon(root.icon); + } + + Item { + id: modalWindowItem + clip: true + width: pane.width + height: pane.height + anchors.margins: 0 + + QtObject { + id: d + readonly property int minWidth: 480 + readonly property int maxWdith: 1280 + readonly property int minHeight: 120 + readonly property int maxHeight: 720 + + function resize() { + var targetWidth = Math.max(titleWidth, pane.width) + var targetHeight = (items ? comboBox.controlHeight : textResult.controlHeight) + 5 * hifi.dimensions.contentSpacing.y + buttons.height + root.width = (targetWidth < d.minWidth) ? d.minWidth : ((targetWidth > d.maxWdith) ? d.maxWidth : targetWidth); + root.height = ((targetHeight < d.minHeight) ? d.minHeight : ((targetHeight > d.maxHeight) ? d.maxHeight : targetHeight)) + ((keyboardEnabled && keyboardRaised) ? (keyboard.raisedHeight + 2 * hifi.dimensions.contentSpacing.y) : 0) + } + } + + Item { + anchors { + top: parent.top + bottom: keyboard.top; + left: parent.left; + right: parent.right; + margins: 0 + bottomMargin: 2 * hifi.dimensions.contentSpacing.y + } + + // FIXME make a text field type that can be bound to a history for autocompletion + TextField { + id: textResult + label: root.label + visible: items ? false : true + anchors { + left: parent.left; + right: parent.right; + bottom: parent.bottom + } + KeyNavigation.down: acceptButton + KeyNavigation.tab: acceptButton + } + + ComboBox { + id: comboBox + label: root.label + visible: items ? true : false + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + model: items ? items : [] + KeyNavigation.down: acceptButton + KeyNavigation.tab: acceptButton + } + } + + property alias keyboardOverride: root.keyboardOverride + property alias keyboardRaised: root.keyboardRaised + property alias punctuationMode: root.punctuationMode + Keyboard { + id: keyboard + raised: keyboardEnabled && keyboardRaised + numeric: punctuationMode + anchors { + left: parent.left + right: parent.right + bottom: buttons.top + bottomMargin: raised ? 2 * hifi.dimensions.contentSpacing.y : 0 + } + } + + Flow { + id: buttons + spacing: hifi.dimensions.contentSpacing.x + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + layoutDirection: Qt.RightToLeft + anchors { + bottom: parent.bottom + right: parent.right + margins: 0 + bottomMargin: hifi.dimensions.contentSpacing.y + } + Button { + id: cancelButton + action: cancelAction + KeyNavigation.left: acceptButton + KeyNavigation.up: items ? comboBox : textResult + KeyNavigation.backtab: acceptButton + } + Button { + id: acceptButton + action: acceptAction + KeyNavigation.right: cancelButton + KeyNavigation.up: items ? comboBox : textResult + KeyNavigation.tab: cancelButton + KeyNavigation.backtab: items ? comboBox : textResult + } + } + + Action { + id: cancelAction + text: qsTr("Cancel"); + shortcut: "Esc" + onTriggered: { + root.canceled(); + // FIXME we are leaking memory to avoid a crash + // root.destroy(); + + root.disableFade = true + visible = false; + } + } + + Action { + id: acceptAction + text: qsTr("OK"); + shortcut: "Return" + onTriggered: { + root.result = items ? comboBox.currentText : textResult.text + root.selected(root.result); + // FIXME we are leaking memory to avoid a crash + // root.destroy(); + + root.disableFade = true + visible = false; + } + } + } + + Keys.onPressed: { + if (!visible) { + return + } + + switch (event.key) { + case Qt.Key_Escape: + case Qt.Key_Back: + cancelAction.trigger() + event.accepted = true; + break; + + case Qt.Key_Return: + case Qt.Key_Enter: + if (acceptButton.focus) { + acceptAction.trigger() + } else if (cancelButton.focus) { + cancelAction.trigger() + } else if (comboBox.focus || comboBox.popup.focus) { + comboBox.showList() + } + event.accepted = true; + break; + } + } + + Component.onCompleted: { + keyboardEnabled = HMD.active; + updateIcon(); + d.resize(); + if (items) { + comboBox.forceActiveFocus() + } else { + textResult.forceActiveFocus() + } + } +} diff --git a/interface/resources/qml/dialogs/assetDialog/+android/AssetDialogContent.qml b/interface/resources/qml/dialogs/assetDialog/+android/AssetDialogContent.qml new file mode 100644 index 0000000000..54bdb0a888 --- /dev/null +++ b/interface/resources/qml/dialogs/assetDialog/+android/AssetDialogContent.qml @@ -0,0 +1,533 @@ +// +// AssetDialogContent.qml +// +// Created by David Rowe on 19 Apr 2017 +// Copyright 2017 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.7 +import QtQuick.Controls 1.5 + +import "../../controls-uit" +import "../../styles-uit" + +import "../fileDialog" + +Item { + // Set from OffscreenUi::assetDialog() + property alias dir: assetTableModel.folder + property alias filter: selectionType.filtersString // FIXME: Currently only supports simple filters, "*.xxx". + property int options // Not used. + + property bool selectDirectory: false + + // Not implemented. + //property bool saveDialog: false; + //property bool multiSelect: false; + + property bool singleClickNavigate: false + + HifiConstants { id: hifi } + + Component.onCompleted: { + homeButton.destination = dir; + + if (selectDirectory) { + d.currentSelectionIsFolder = true; + d.currentSelectionPath = assetTableModel.folder; + } + + assetTableView.forceActiveFocus(); + } + + Item { + id: assetDialogItem + anchors.fill: parent + clip: true + + MouseArea { + // Clear selection when click on internal unused area. + anchors.fill: parent + drag.target: root + onClicked: { + d.clearSelection(); + frame.forceActiveFocus(); + assetTableView.forceActiveFocus(); + } + } + + Row { + id: navControls + anchors { + top: parent.top + topMargin: hifi.dimensions.contentMargin.y + left: parent.left + } + spacing: hifi.dimensions.contentSpacing.x + + GlyphButton { + id: upButton + glyph: hifi.glyphs.levelUp + width: height + size: 30 + enabled: assetTableModel.parentFolder !== "" + onClicked: d.navigateUp(); + } + + GlyphButton { + id: homeButton + property string destination: "" + glyph: hifi.glyphs.home + size: 28 + width: height + enabled: destination !== "" + //onClicked: d.navigateHome(); + onClicked: assetTableModel.folder = destination; + } + } + + ComboBox { + id: pathSelector + anchors { + top: parent.top + topMargin: hifi.dimensions.contentMargin.y + left: navControls.right + leftMargin: hifi.dimensions.contentSpacing.x + right: parent.right + } + z: 10 + + property string lastValidFolder: assetTableModel.folder + + function calculatePathChoices(folder) { + var folders = folder.split("/"), + choices = [], + i, length; + + if (folders[folders.length - 1] === "") { + folders.pop(); + } + + choices.push(folders[0]); + + for (i = 1, length = folders.length; i < length; i++) { + choices.push(choices[i - 1] + "/" + folders[i]); + } + + if (folders[0] === "") { + choices[0] = "/"; + } + + choices.reverse(); + + if (choices.length > 0) { + pathSelector.model = choices; + } + } + + onLastValidFolderChanged: { + var folder = lastValidFolder; + calculatePathChoices(folder); + } + + onCurrentTextChanged: { + var folder = currentText; + + if (folder !== "/") { + folder += "/"; + } + + if (folder !== assetTableModel.folder) { + if (root.selectDirectory) { + currentSelection.text = currentText; + d.currentSelectionPath = currentText; + } + assetTableModel.folder = folder; + assetTableView.forceActiveFocus(); + } + } + } + + QtObject { + id: d + + property string currentSelectionPath + property bool currentSelectionIsFolder + property var tableViewConnection: Connections { target: assetTableView; onCurrentRowChanged: d.update(); } + + function update() { + var row = assetTableView.currentRow; + + if (row === -1) { + if (!root.selectDirectory) { + currentSelection.text = ""; + currentSelectionIsFolder = false; + } + return; + } + + var rowInfo = assetTableModel.get(row); + currentSelectionPath = rowInfo.filePath; + currentSelectionIsFolder = rowInfo.fileIsDir; + if (root.selectDirectory || !currentSelectionIsFolder) { + currentSelection.text = currentSelectionPath; + } else { + currentSelection.text = ""; + } + } + + function navigateUp() { + if (assetTableModel.parentFolder !== "") { + assetTableModel.folder = assetTableModel.parentFolder; + return true; + } + return false; + } + + function navigateHome() { + assetTableModel.folder = homeButton.destination; + return true; + } + + function clearSelection() { + assetTableView.selection.clear(); + assetTableView.currentRow = -1; + update(); + } + } + + ListModel { + id: assetTableModel + + property string folder + property string parentFolder: "" + readonly property string rootFolder: "/" + + onFolderChanged: { + parentFolder = calculateParentFolder(); + update(); + } + + function calculateParentFolder() { + if (folder !== "/") { + return folder.slice(0, folder.slice(0, -1).lastIndexOf("/") + 1); + } + return ""; + } + + function isFolder(row) { + if (row === -1) { + return false; + } + return get(row).fileIsDir; + } + + function onGetAllMappings(error, map) { + var mappings, + fileTypeFilter, + index, + path, + fileName, + fileType, + fileIsDir, + isValid, + subDirectory, + subDirectories = [], + fileNameSort, + rows = 0, + lower, + middle, + upper, + i, + length; + + clear(); + + if (error === "") { + mappings = Object.keys(map); + fileTypeFilter = filter.replace("*", "").toLowerCase(); + + for (i = 0, length = mappings.length; i < length; i++) { + index = mappings[i].lastIndexOf("/"); + + path = mappings[i].slice(0, mappings[i].lastIndexOf("/") + 1); + fileName = mappings[i].slice(path.length); + fileType = fileName.slice(fileName.lastIndexOf(".")); + fileIsDir = false; + isValid = false; + + if (fileType.toLowerCase() === fileTypeFilter) { + if (path === folder) { + isValid = !selectDirectory; + } else if (path.length > folder.length) { + subDirectory = path.slice(folder.length); + index = subDirectory.indexOf("/"); + if (index === subDirectory.lastIndexOf("/")) { + fileName = subDirectory.slice(0, index); + if (subDirectories.indexOf(fileName) === -1) { + fileIsDir = true; + isValid = true; + subDirectories.push(fileName); + } + } + } + } + + if (isValid) { + fileNameSort = (fileIsDir ? "*" : "") + fileName.toLowerCase(); + + lower = 0; + upper = rows; + while (lower < upper) { + middle = Math.floor((lower + upper) / 2); + var lessThan; + if (fileNameSort < get(middle)["fileNameSort"]) { + lessThan = true; + upper = middle; + } else { + lessThan = false; + lower = middle + 1; + } + } + + insert(lower, { + fileName: fileName, + filePath: path + (fileIsDir ? "" : fileName), + fileIsDir: fileIsDir, + fileNameSort: fileNameSort + }); + + rows++; + } + } + + } else { + console.log("Error getting mappings from Asset Server"); + } + } + + function update() { + d.clearSelection(); + clear(); + Assets.getAllMappings(onGetAllMappings); + } + } + + Table { + id: assetTableView + colorScheme: hifi.colorSchemes.light + anchors { + top: navControls.bottom + topMargin: hifi.dimensions.contentSpacing.y + left: parent.left + right: parent.right + bottom: currentSelection.top + bottomMargin: hifi.dimensions.contentSpacing.y + currentSelection.controlHeight - currentSelection.height + } + + model: assetTableModel + + focus: true + + onClicked: { + if (singleClickNavigate) { + navigateToRow(row); + } + } + + onDoubleClicked: navigateToRow(row); + Keys.onReturnPressed: navigateToCurrentRow(); + Keys.onEnterPressed: navigateToCurrentRow(); + + itemDelegate: Item { + clip: true + + FiraSansSemiBold { + text: styleData.value + elide: styleData.elideMode + anchors { + left: parent.left + leftMargin: hifi.dimensions.tablePadding + right: parent.right + rightMargin: hifi.dimensions.tablePadding + verticalCenter: parent.verticalCenter + } + size: hifi.fontSizes.tableText + color: hifi.colors.baseGrayHighlight + font.family: (styleData.row !== -1 && assetTableView.model.get(styleData.row).fileIsDir) + ? "Fira Sans SemiBold" : "Fira Sans" + } + } + + TableViewColumn { + id: fileNameColumn + role: "fileName" + title: "Name" + width: assetTableView.width + movable: false + resizable: false + } + + function navigateToRow(row) { + currentRow = row; + navigateToCurrentRow(); + } + + function navigateToCurrentRow() { + if (model.isFolder(currentRow)) { + model.folder = model.get(currentRow).filePath; + } else { + okAction.trigger(); + } + } + + Timer { + id: prefixClearTimer + interval: 1000 + repeat: false + running: false + onTriggered: assetTableView.prefix = ""; + } + + property string prefix: "" + + function addToPrefix(event) { + if (!event.text || event.text === "") { + return false; + } + var newPrefix = prefix + event.text.toLowerCase(); + var matchedIndex = -1; + for (var i = 0; i < model.count; ++i) { + var name = model.get(i).fileName.toLowerCase(); + if (0 === name.indexOf(newPrefix)) { + matchedIndex = i; + break; + } + } + + if (matchedIndex !== -1) { + assetTableView.selection.clear(); + assetTableView.selection.select(matchedIndex); + assetTableView.currentRow = matchedIndex; + assetTableView.prefix = newPrefix; + } + prefixClearTimer.restart(); + return true; + } + + Keys.onPressed: { + switch (event.key) { + case Qt.Key_Backspace: + case Qt.Key_Tab: + case Qt.Key_Backtab: + event.accepted = false; + break; + + default: + if (addToPrefix(event)) { + event.accepted = true + } else { + event.accepted = false; + } + break; + } + } + } + + TextField { + id: currentSelection + label: selectDirectory ? "Directory:" : "File name:" + anchors { + left: parent.left + right: selectionType.visible ? selectionType.left: parent.right + rightMargin: selectionType.visible ? hifi.dimensions.contentSpacing.x : 0 + bottom: buttonRow.top + bottomMargin: hifi.dimensions.contentSpacing.y + } + readOnly: true + activeFocusOnTab: !readOnly + onActiveFocusChanged: if (activeFocus) { selectAll(); } + onAccepted: okAction.trigger(); + } + + FileTypeSelection { + id: selectionType + anchors { + top: currentSelection.top + left: buttonRow.left + right: parent.right + } + visible: !selectDirectory && filtersCount > 1 + KeyNavigation.left: assetTableView + KeyNavigation.right: openButton + } + + Action { + id: okAction + text: currentSelection.text && root.selectDirectory && assetTableView.currentRow === -1 ? "Choose" : "Open" + enabled: currentSelection.text || !root.selectDirectory && d.currentSelectionIsFolder ? true : false + onTriggered: { + if (!root.selectDirectory && !d.currentSelectionIsFolder + || root.selectDirectory && assetTableView.currentRow === -1) { + selectedAsset(d.currentSelectionPath); + root.destroy(); + } else { + assetTableView.navigateToCurrentRow(); + } + } + } + + Action { + id: cancelAction + text: "Cancel" + onTriggered: { + canceled(); + root.destroy(); + } + } + + Row { + id: buttonRow + anchors { + right: parent.right + bottom: parent.bottom + } + spacing: hifi.dimensions.contentSpacing.y + + Button { + id: openButton + color: hifi.buttons.blue + action: okAction + Keys.onReturnPressed: okAction.trigger() + KeyNavigation.up: selectionType + KeyNavigation.left: selectionType + KeyNavigation.right: cancelButton + } + + Button { + id: cancelButton + action: cancelAction + KeyNavigation.up: selectionType + KeyNavigation.left: openButton + KeyNavigation.right: assetTableView.contentItem + Keys.onReturnPressed: { canceled(); root.enabled = false } + } + } + } + + Keys.onPressed: { + switch (event.key) { + case Qt.Key_Backspace: + event.accepted = d.navigateUp(); + break; + + case Qt.Key_Home: + event.accepted = d.navigateHome(); + break; + + } + } +}