From 4e4627d03951fef18c802c56f84f961fde0f348d Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 26 Jan 2016 15:54:26 -0800 Subject: [PATCH 01/27] avatar-animation.json: Updated standard animations --- .../defaultAvatar_full/avatar-animation.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index d510e7b966..637ed68455 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -420,7 +420,7 @@ "id": "idleStand", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/idle.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, @@ -432,7 +432,7 @@ "id": "idleTalk", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/talk/talk.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/talk.fbx", "startFrame": 0.0, "endFrame": 801.0, "timeScale": 1.0, @@ -457,7 +457,7 @@ "id": "walkFwdShort", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_short_fwd.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_short_fwd.fbx", "startFrame": 0.0, "endFrame": 39.0, "timeScale": 1.0, @@ -469,7 +469,7 @@ "id": "walkFwdNormal", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_fwd.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_fwd.fbx", "startFrame": 0.0, "endFrame": 35.0, "timeScale": 1.0, @@ -481,7 +481,7 @@ "id": "walkFwdRun", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/run_fwd.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/run_fwd.fbx", "startFrame": 0.0, "endFrame": 21.0, "timeScale": 1.0, @@ -495,7 +495,7 @@ "id": "idleToWalkFwd", "type": "clip", "data": { - "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims/idle_to_walk.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle_to_walk.fbx", "startFrame": 1.0, "endFrame": 19.0, "timeScale": 1.0, @@ -518,7 +518,7 @@ "id": "walkBwdShort", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_short_bwd.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_short_bwd.fbx", "startFrame": 0.0, "endFrame": 38.0, "timeScale": 1.0, @@ -530,7 +530,7 @@ "id": "walkBwdNormal", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/walk_bwd.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_bwd.fbx", "startFrame": 0.0, "endFrame": 36.0, "timeScale": 1.0, @@ -544,7 +544,7 @@ "id": "turnLeft", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/turn_left.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/turn_left.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -556,7 +556,7 @@ "id": "turnRight", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/turn_right.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/turn_right.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -579,7 +579,7 @@ "id": "strafeLeftShort", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_short_left.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_short_left.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -591,7 +591,7 @@ "id": "strafeLeftNormal", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_left.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_left.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -616,7 +616,7 @@ "id": "strafeRightShort", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_short_right.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_short_right.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -628,7 +628,7 @@ "id": "strafeRightNormal", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_right.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_right.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -642,7 +642,7 @@ "id": "awayIntro", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/kneel/kneel.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 0.0, "endFrame": 83.0, "timeScale": 1.0, @@ -654,7 +654,7 @@ "id": "away", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/kneel/kneel.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 83.0, "endFrame": 84.0, "timeScale": 1.0, @@ -666,7 +666,7 @@ "id": "awayOutro", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/kneel/kneel.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 84.0, "endFrame": 167.0, "timeScale": 1.0, @@ -678,7 +678,7 @@ "id": "fly", "type": "clip", "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims/fly.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/fly.fbx", "startFrame": 1.0, "endFrame": 80.0, "timeScale": 1.0, @@ -700,7 +700,7 @@ "id": "userAnimA", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/idle.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, @@ -712,7 +712,7 @@ "id": "userAnimB", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/idle.fbx", + "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, From 191e6090e7adaacfbb77eb332adc7bef97a24e79 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 28 Jan 2016 11:36:23 -0800 Subject: [PATCH 02/27] Moves zone props to top of entity props panel --- examples/html/entityProperties.html | 270 ++++++++++++++-------------- 1 file changed, 136 insertions(+), 134 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 898f2bea6d..86dbeebe9f 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -976,6 +976,142 @@ + +
+ +
+ +
+ Stage Sun Model Enabled + + + +
+ +
+ +
+ +
+
Light Color
+
+
+
R
+
G
+
B
+
+
+ +
+
Light Intensity
+
+ +
+
+ +
+
Light Direction
+
+
Pitch
+
Yaw
+
Roll
+
+
+ +
+
Ambient Intensity
+
+ +
+
+ + +
+
Ambient URL
+
+ +
+
+ +
+ +
+ +
+
Stage Latitude
+
+ +
+
+
+
Stage Longitude
+
+ +
+
+
+
Stage Altitude
+
+ +
+
+ +
+ Automatically calculate stage hour and day from location and clock. + + + +
+ +
+
Stage Day
+
+ +
+
+
+
Stage Hour
+
+ +
+
+ +
+ +
+ +
+
Background Mode
+
+ +
+
+ + +
+ +
+ +
+
Skybox Color
+
+
+
R
+
G
+
B
+
+
+
+
Skybox URL
+
+ +
+
+ +
@@ -1440,139 +1576,5 @@
-
- -
- -
- Stage Sun Model Enabled - - - -
- -
- -
- -
-
Light Color
-
-
-
R
-
G
-
B
-
-
- -
-
Light Intensity
-
- -
-
- -
-
Light Direction
-
-
Pitch
-
Yaw
-
Roll
-
-
- -
-
Ambient Intensity
-
- -
-
- - -
-
Ambient URL
-
- -
-
- -
- -
- -
-
Stage Latitude
-
- -
-
-
-
Stage Longitude
-
- -
-
-
-
Stage Altitude
-
- -
-
- -
- Automatically calculate stage hour and day from location and clock. - - - -
- -
-
Stage Day
-
- -
-
-
-
Stage Hour
-
- -
-
- -
- -
- -
-
Background Mode
-
- -
-
- - -
- -
- -
-
Skybox Color
-
-
-
R
-
G
-
B
-
-
-
-
Skybox URL
-
- -
-
- From 40c66a94beb60a3490c54cfca3b8e30091270a78 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 28 Jan 2016 11:44:50 -0800 Subject: [PATCH 03/27] Moves text props to top of Entity Props panel --- examples/html/entityProperties.html | 72 +++++++++++++++-------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 898f2bea6d..8ea43810fd 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -976,6 +976,42 @@ +
+ +
+ +
+
Text Content
+
+ +
+
+
+
Line Height
+
+ +
+
+
+
Text Color
+
+
+
R
+
G
+
B
+
+
+
+
Background Color
+
+
+
R
+
G
+
B
+
+
+ +
@@ -1365,41 +1401,7 @@
-
- -
- -
-
Text Content
-
- -
-
-
-
Line Height
-
- -
-
-
-
Text Color
-
-
-
R
-
G
-
B
-
-
-
-
Background Color
-
-
-
R
-
G
-
B
-
-
- +
From 3fff5868e8429d4b09da32244864cf21cb9c0088 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 28 Jan 2016 11:57:33 -0800 Subject: [PATCH 04/27] Fix syntax error --- examples/html/entityProperties.html | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 86dbeebe9f..28db85a2fd 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -976,8 +976,7 @@
- -
+
@@ -1110,7 +1109,6 @@
-
@@ -1574,7 +1572,6 @@
- - + - + \ No newline at end of file From c41500f9d2a0bcd866f059d3cf95af7f1fd5044d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 12:21:44 -0800 Subject: [PATCH 05/27] Running scripts can now show script URL --- .../resources/qml/dialogs/RunningScripts.qml | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/dialogs/RunningScripts.qml b/interface/resources/qml/dialogs/RunningScripts.qml index eb56b59b66..5aec9ef3cf 100644 --- a/interface/resources/qml/dialogs/RunningScripts.qml +++ b/interface/resources/qml/dialogs/RunningScripts.qml @@ -123,26 +123,42 @@ Window { } ListView { + id: listView clip: true anchors { fill: parent; margins: 0 } model: runningScriptsModel delegate: Rectangle { + id: rectangle + clip: true radius: 3 anchors { left: parent.left; right: parent.right } - height: scriptName.height + 12 - color: index % 2 ? "#ddd" : "#eee" + height: scriptName.height + 12 + (ListView.isCurrentItem ? scriptName.height + 6 : 0) + color: ListView.isCurrentItem ? "#39f" : + index % 2 ? "#ddd" : "#eee" Text { - anchors { left: parent.left; leftMargin: 4; verticalCenter: parent.verticalCenter } id: scriptName + anchors { left: parent.left; leftMargin: 4; top: parent.top; topMargin:6 } text: name } + Text { + id: scriptUrl + anchors { left: scriptName.left; right: parent.right; rightMargin: 4; top: scriptName.bottom; topMargin: 6 } + text: url + elide: Text.ElideMiddle + } + + MouseArea { + anchors.fill: parent + onClicked: listView.currentIndex = index + } + Row { - anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenter: scriptName.verticalCenter anchors.right: parent.right anchors.rightMargin: 4 spacing: 4 From c30109ec29130502083ce5f42fc60c88adfc8f1e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 28 Jan 2016 13:21:48 -0800 Subject: [PATCH 06/27] trying to sync again --- examples/html/entityProperties.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 28db85a2fd..848e16fae8 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -976,7 +976,7 @@ -
+
@@ -1116,7 +1116,7 @@
-
Href
+
Href - Hifi://address
From 8710029604e567fd73af44fecc235c963084c9c0 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 28 Jan 2016 14:12:52 -0800 Subject: [PATCH 07/27] Changed urls to http and updated hand poses. --- .../defaultAvatar_full/avatar-animation.json | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 637ed68455..b71bbc648b 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -145,7 +145,7 @@ "id": "rightHandGraspOpen", "type": "clip", "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/hydra_pose_open_right.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/hydra_pose_open_right.fbx", "startFrame": 0.0, "endFrame": 0.0, "timeScale": 1.0, @@ -157,7 +157,7 @@ "id": "rightHandGraspClosed", "type": "clip", "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/hydra_pose_closed_right.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/hydra_pose_closed_right.fbx", "startFrame": 0.0, "endFrame": 0.0, "timeScale": 1.0, @@ -205,7 +205,7 @@ "id": "leftHandGraspOpen", "type": "clip", "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/hydra_pose_open_left.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/hydra_pose_open_left.fbx", "startFrame": 0.0, "endFrame": 0.0, "timeScale": 1.0, @@ -217,7 +217,7 @@ "id": "leftHandGraspClosed", "type": "clip", "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/hydra_pose_closed_left.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/hydra_pose_closed_left.fbx", "startFrame": 10.0, "endFrame": 10.0, "timeScale": 1.0, @@ -420,7 +420,7 @@ "id": "idleStand", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, @@ -432,7 +432,7 @@ "id": "idleTalk", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/talk.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/talk.fbx", "startFrame": 0.0, "endFrame": 801.0, "timeScale": 1.0, @@ -457,7 +457,7 @@ "id": "walkFwdShort", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_short_fwd.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_short_fwd.fbx", "startFrame": 0.0, "endFrame": 39.0, "timeScale": 1.0, @@ -469,7 +469,7 @@ "id": "walkFwdNormal", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_fwd.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_fwd.fbx", "startFrame": 0.0, "endFrame": 35.0, "timeScale": 1.0, @@ -481,7 +481,7 @@ "id": "walkFwdRun", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/run_fwd.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/run_fwd.fbx", "startFrame": 0.0, "endFrame": 21.0, "timeScale": 1.0, @@ -495,7 +495,7 @@ "id": "idleToWalkFwd", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle_to_walk.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle_to_walk.fbx", "startFrame": 1.0, "endFrame": 19.0, "timeScale": 1.0, @@ -518,7 +518,7 @@ "id": "walkBwdShort", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_short_bwd.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_short_bwd.fbx", "startFrame": 0.0, "endFrame": 38.0, "timeScale": 1.0, @@ -530,7 +530,7 @@ "id": "walkBwdNormal", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_bwd.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_bwd.fbx", "startFrame": 0.0, "endFrame": 36.0, "timeScale": 1.0, @@ -544,7 +544,7 @@ "id": "turnLeft", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/turn_left.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/turn_left.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -556,7 +556,7 @@ "id": "turnRight", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/turn_right.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/turn_right.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -579,7 +579,7 @@ "id": "strafeLeftShort", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_short_left.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_short_left.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -591,7 +591,7 @@ "id": "strafeLeftNormal", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_left.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_left.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -616,7 +616,7 @@ "id": "strafeRightShort", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_short_right.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_short_right.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -628,7 +628,7 @@ "id": "strafeRightNormal", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_right.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_right.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -642,7 +642,7 @@ "id": "awayIntro", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 0.0, "endFrame": 83.0, "timeScale": 1.0, @@ -654,7 +654,7 @@ "id": "away", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 83.0, "endFrame": 84.0, "timeScale": 1.0, @@ -666,7 +666,7 @@ "id": "awayOutro", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 84.0, "endFrame": 167.0, "timeScale": 1.0, @@ -678,7 +678,7 @@ "id": "fly", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/fly.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/fly.fbx", "startFrame": 1.0, "endFrame": 80.0, "timeScale": 1.0, @@ -700,7 +700,7 @@ "id": "userAnimA", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, @@ -712,7 +712,7 @@ "id": "userAnimB", "type": "clip", "data": { - "url": "https://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", + "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, From d743ea2c9be5b3f07f0aa3ad49906c5a00bde396 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 28 Jan 2016 14:20:10 -0800 Subject: [PATCH 08/27] Changed urls from s3-us-west-1 to hifi-content.s3 --- .../defaultAvatar_full/avatar-animation.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index b71bbc648b..42ff64abc6 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -420,7 +420,7 @@ "id": "idleStand", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, @@ -432,7 +432,7 @@ "id": "idleTalk", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/talk.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/talk.fbx", "startFrame": 0.0, "endFrame": 801.0, "timeScale": 1.0, @@ -457,7 +457,7 @@ "id": "walkFwdShort", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_short_fwd.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/walk_short_fwd.fbx", "startFrame": 0.0, "endFrame": 39.0, "timeScale": 1.0, @@ -469,7 +469,7 @@ "id": "walkFwdNormal", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_fwd.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/walk_fwd.fbx", "startFrame": 0.0, "endFrame": 35.0, "timeScale": 1.0, @@ -481,7 +481,7 @@ "id": "walkFwdRun", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/run_fwd.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/run_fwd.fbx", "startFrame": 0.0, "endFrame": 21.0, "timeScale": 1.0, @@ -495,7 +495,7 @@ "id": "idleToWalkFwd", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle_to_walk.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/idle_to_walk.fbx", "startFrame": 1.0, "endFrame": 19.0, "timeScale": 1.0, @@ -518,7 +518,7 @@ "id": "walkBwdShort", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_short_bwd.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/walk_short_bwd.fbx", "startFrame": 0.0, "endFrame": 38.0, "timeScale": 1.0, @@ -530,7 +530,7 @@ "id": "walkBwdNormal", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/walk_bwd.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/walk_bwd.fbx", "startFrame": 0.0, "endFrame": 36.0, "timeScale": 1.0, @@ -544,7 +544,7 @@ "id": "turnLeft", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/turn_left.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/turn_left.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -556,7 +556,7 @@ "id": "turnRight", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/turn_right.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/turn_right.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -579,7 +579,7 @@ "id": "strafeLeftShort", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_short_left.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/side_step_short_left.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -591,7 +591,7 @@ "id": "strafeLeftNormal", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_left.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/side_step_left.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -616,7 +616,7 @@ "id": "strafeRightShort", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_short_right.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/side_step_short_right.fbx", "startFrame": 0.0, "endFrame": 28.0, "timeScale": 1.0, @@ -628,7 +628,7 @@ "id": "strafeRightNormal", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/side_step_right.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/side_step_right.fbx", "startFrame": 0.0, "endFrame": 30.0, "timeScale": 1.0, @@ -642,7 +642,7 @@ "id": "awayIntro", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 0.0, "endFrame": 83.0, "timeScale": 1.0, @@ -654,7 +654,7 @@ "id": "away", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 83.0, "endFrame": 84.0, "timeScale": 1.0, @@ -666,7 +666,7 @@ "id": "awayOutro", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/kneel.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/kneel.fbx", "startFrame": 84.0, "endFrame": 167.0, "timeScale": 1.0, @@ -678,7 +678,7 @@ "id": "fly", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/fly.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/fly.fbx", "startFrame": 1.0, "endFrame": 80.0, "timeScale": 1.0, @@ -700,7 +700,7 @@ "id": "userAnimA", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, @@ -712,7 +712,7 @@ "id": "userAnimB", "type": "clip", "data": { - "url": "http://s3-us-west-1.amazonaws.com/hifi-content/ozan/dev/anim/standard_anims_160127/idle.fbx", + "url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/idle.fbx", "startFrame": 0.0, "endFrame": 90.0, "timeScale": 1.0, From af1180aadb2840ef560996a609508cdbf3279dc7 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 15:47:42 -0800 Subject: [PATCH 09/27] Fix combobox in modal windows --- interface/resources/qml/controls/ComboBox.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/controls/ComboBox.qml b/interface/resources/qml/controls/ComboBox.qml index e22bc8e664..960ae8127a 100644 --- a/interface/resources/qml/controls/ComboBox.qml +++ b/interface/resources/qml/controls/ComboBox.qml @@ -91,8 +91,10 @@ FocusScope { id: popup parent: desktop anchors.fill: parent + z: desktop.zLevels.menu visible: false focus: true + MouseArea { anchors.fill: parent onClicked: hideList(); @@ -116,7 +118,7 @@ FocusScope { ListView { id: listView - height: textView.height * count + height: textField.height * count * 1.4 model: root.model highlight: Rectangle{ width: listView.currentItem ? listView.currentItem.width : 0 From 1324525ecc363c40295ec57f88a8469de6aab8ad Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 15:50:57 -0800 Subject: [PATCH 10/27] Make file dialog compatible with QFileDialog::getOpenFile --- interface/resources/qml/desktop/Desktop.qml | 6 ++ .../resources/qml/dialogs/FileDialog.qml | 36 +++++++---- .../dialogs/fileDialog/FileTypeSelection.qml | 27 ++++++++ libraries/ui/src/OffscreenUi.cpp | 62 +++++++++++++++++++ libraries/ui/src/OffscreenUi.h | 2 +- 5 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 interface/resources/qml/dialogs/fileDialog/FileTypeSelection.qml diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 8c4f73c200..b610dbf73c 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -257,6 +257,12 @@ FocusScope { return queryDialogBuilder.createObject(desktop, properties); } + Component { id: fileDialogBuilder; FileDialog { } } + function fileOpenDialog(properties) { + return fileDialogBuilder.createObject(desktop, properties); + } + + MenuMouseHandler { id: menuPopperUpper } function popupMenu(point) { menuPopperUpper.popup(desktop, rootMenu.items, point); diff --git a/interface/resources/qml/dialogs/FileDialog.qml b/interface/resources/qml/dialogs/FileDialog.qml index 9d2278f460..353e2df494 100644 --- a/interface/resources/qml/dialogs/FileDialog.qml +++ b/interface/resources/qml/dialogs/FileDialog.qml @@ -12,6 +12,27 @@ import "fileDialog" //FIXME implement shortcuts for favorite location ModalWindow { id: root + resizable: true + width: 640 + height: 480 + + 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: model.folder; + // Set from OffscreenUi::getOpenFile() + property alias filter: selectionType.filtersString; + // Set from OffscreenUi::getOpenFile() + property int options; // <-- FIXME unused property bool selectDirectory: false; property bool showHidden: false; @@ -19,17 +40,11 @@ ModalWindow { property bool multiSelect: false; // FIXME implement property bool saveDialog: false; + property var helper: fileDialogHelper + property alias model: fileTableView.model signal selectedFile(var file); signal canceled(); - resizable: true - width: 640 - height: 480 - - property var helper: fileDialogHelper - property alias model: fileTableView.model - property alias filterModel: selectionType.model - property alias folder: model.folder Rectangle { anchors.fill: parent @@ -120,6 +135,7 @@ ModalWindow { onDoubleClicked: navigateToRow(row); model: FolderListModel { id: model + nameFilters: selectionType.currentFilter showDirsFirst: true showDotAndDotDot: false showFiles: !root.selectDirectory @@ -157,12 +173,10 @@ ModalWindow { readOnly: true } - ComboBox { + FileTypeSelection { id: selectionType anchors { bottom: buttonRow.top; bottomMargin: 8; right: parent.right; rightMargin: 8; left: buttonRow.left } visible: !selectDirectory - model: ListModel { ListElement { text: "All Files (*.*)"; filter: "*.*" } } -// onCurrentIndexChanged: model.nameFilters = [ filterModel.get(currentIndex).filter ] KeyNavigation.left: fileTableView KeyNavigation.right: openButton } diff --git a/interface/resources/qml/dialogs/fileDialog/FileTypeSelection.qml b/interface/resources/qml/dialogs/fileDialog/FileTypeSelection.qml new file mode 100644 index 0000000000..a3ab652e32 --- /dev/null +++ b/interface/resources/qml/dialogs/fileDialog/FileTypeSelection.qml @@ -0,0 +1,27 @@ +import QtQuick 2.5 + +import "../../controls" as VrControls + +VrControls.ComboBox { + id: root + property string filtersString: "All Files (*.*)"; + property var currentFilter: [ "*.*" ]; + + // Per http://doc.qt.io/qt-5/qfiledialog.html#getOpenFileName the string can contain + // multiple filters separated by semicolons + // ex: "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" + model: filtersString.split(';;'); + + enabled: model.length > 1 + + onCurrentTextChanged: { + var globRegex = /\((.*)\)$/ + var globs = globRegex.exec(currentText); + if (!globs[1]) { + console.warn("Unable to parse filter " + currentText); + return; + } + currentFilter = globs[1].split(" "); + } +} + diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index d7d28bef84..f399cd95a1 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -412,4 +412,66 @@ void OffscreenUi::toggleMenu(const QPoint& screenPosition) { } +class FileDialogListener : public ModalDialogListener { + Q_OBJECT + + friend class OffscreenUi; + FileDialogListener(QQuickItem* messageBox) : ModalDialogListener(messageBox) { + if (_finished) { + return; + } + connect(_dialog, SIGNAL(selectedFile(QVariant)), this, SLOT(onSelectedFile(QVariant))); + } + +private slots: + void onSelectedFile(QVariant file) { + _result = file; + _finished = true; + disconnect(_dialog); + } +}; + +QString OffscreenUi::fileOpenDialog(const QString& caption, const QString& dir, const QString& filter, QString* selectedFilter, QFileDialog::Options options) { + if (QThread::currentThread() != thread()) { + QString result; + QMetaObject::invokeMethod(this, "fileOpenDialog", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(QString, result), + Q_ARG(QString, caption), + Q_ARG(QString, dir), + Q_ARG(QString, filter), + Q_ARG(QString*, selectedFilter), + Q_ARG(QFileDialog::Options, options)); + return result; + } + + // FIXME support returning the selected filter... somehow? + QVariantMap map; + map.insert("caption", caption); + map.insert("dir", QUrl::fromLocalFile(dir)); + map.insert("filter", filter); + map.insert("options", static_cast(options)); + + QVariant buildDialogResult; + bool invokeResult = QMetaObject::invokeMethod(_desktop, "fileOpenDialog", + Q_RETURN_ARG(QVariant, buildDialogResult), + Q_ARG(QVariant, QVariant::fromValue(map))); + + if (!invokeResult) { + qWarning() << "Failed to create file open dialog"; + return QString(); + } + + QVariant result = FileDialogListener(qvariant_cast(buildDialogResult)).waitForResult(); + if (!result.isValid()) { + return QString(); + } + qDebug() << result.toString(); + return result.toUrl().toLocalFile(); +} + +QString OffscreenUi::getOpenFileName(void* ignored, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) { + return DependencyManager::get()->fileOpenDialog(caption, dir, filter, selectedFilter, options); +} + + #include "OffscreenUi.moc" diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 73307b38f7..8ad6641e06 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -82,11 +82,11 @@ public: Q_INVOKABLE QMessageBox::StandardButton messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton); Q_INVOKABLE QVariant inputDialog(const QString& query, const QString& placeholderText = QString(), const QString& currentValue = QString()); + Q_INVOKABLE QString fileOpenDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); // FIXME implement static QVariant query(const QString& query, const QString& placeholderText = QString(), const QString& currentValue = QString()); - // FIXME implement // Compatibility with QFileDialog::getOpenFileName static QString getOpenFileName(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); From db7e4eee8f15274191da80c3bb9b8aab3ad8ff42 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 15:52:11 -0800 Subject: [PATCH 11/27] Make Ctrl-O and 'Running Scripts->load file' follow the same code path --- .../resources/qml/dialogs/RunningScripts.qml | 60 ++++++++----------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/interface/resources/qml/dialogs/RunningScripts.qml b/interface/resources/qml/dialogs/RunningScripts.qml index 5aec9ef3cf..8b148c6bef 100644 --- a/interface/resources/qml/dialogs/RunningScripts.qml +++ b/interface/resources/qml/dialogs/RunningScripts.qml @@ -72,23 +72,6 @@ Window { scripts.stopAllScripts(); } - Component { - id: fileDialogBuilder - FileDialog { } - } - - function loadFromFile() { - var fileDialog = fileDialogBuilder.createObject(desktop, { filterModel: fileFilters }); - fileDialog.canceled.connect(function(){ - console.debug("Cancelled file open") - }) - - fileDialog.selectedFile.connect(function(file){ - console.debug("Selected " + file) - scripts.loadOneScript(file); - }) - } - Rectangle { color: "white" anchors.fill: parent @@ -201,31 +184,38 @@ Window { anchors.bottomMargin: 8 anchors.right: parent.right - // For some reason trigginer an API that enters - // an internal event loop directly from the button clicked - // trigger below causes the appliction to behave oddly. - // Most likely because the button onClicked handling is never - // completed until the function returns. - // FIXME find a better way of handling the input dialogs that - // doesn't trigger this. - Timer { - id: asyncAction - interval: 50 - repeat: false - running: false - onTriggered: ApplicationInterface.loadScriptURLDialog(); - } Button { text: "from URL"; - onClicked: { - focus = false; - asyncAction.running = true; + onClicked: fromUrlTimer.running = true; + + // For some reason trigginer an API that enters + // an internal event loop directly from the button clicked + // trigger below causes the appliction to behave oddly. + // Most likely because the button onClicked handling is never + // completed until the function returns. + // FIXME find a better way of handling the input dialogs that + // doesn't trigger this. + Timer { + id: fromUrlTimer + interval: 5 + repeat: false + running: false + onTriggered: ApplicationInterface.loadScriptURLDialog(); } } + Button { text: "from Disk" - onClicked: loadFromFile(); + onClicked: fromDiskTimer.running = true; + + Timer { + id: fromDiskTimer + interval: 5 + repeat: false + running: false + onTriggered: ApplicationInterface.loadDialog(); + } } } From aa03241dd9ba8a52899c3e7167816927d2f6d70c Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 15:53:04 -0800 Subject: [PATCH 12/27] Make all load script dialogs QML and respect previous script location --- interface/src/Application.cpp | 21 ++++++++++++++----- interface/src/Application.h | 4 ++++ interface/src/ui/ScriptEditorWidget.cpp | 4 ++-- interface/src/ui/ScriptEditorWindow.cpp | 7 +++---- libraries/script-engine/src/ScriptEngines.cpp | 14 +------------ libraries/script-engine/src/ScriptEngines.h | 6 ------ 6 files changed, 26 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8e0d46bc81..0bd0031740 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -416,7 +416,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _aboutToQuit(false), _notifiedPacketVersionMismatchThisDomain(false), _maxOctreePPS(maxOctreePacketsPerSecond.get()), - _lastFaceTrackerUpdate(0) + _lastFaceTrackerUpdate(0), + _previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION) { thread()->setObjectName("Main Thread"); @@ -4501,14 +4502,24 @@ void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject } void Application::loadDialog() { - // To be migratd to QML - QString fileNameString = QFileDialog::getOpenFileName( - _glWidget, tr("Open Script"), "", tr("JavaScript Files (*.js)")); - if (!fileNameString.isEmpty()) { + auto scriptEngines = DependencyManager::get(); + QString fileNameString = OffscreenUi::getOpenFileName( + _glWidget, tr("Open Script"), getPreviousScriptLocation(), tr("JavaScript Files (*.js)")); + if (!fileNameString.isEmpty() && QFile(fileNameString).exists()) { + setPreviousScriptLocation(QFileInfo(fileNameString).absolutePath()); DependencyManager::get()->loadScript(fileNameString, true, false, false, true); // Don't load from cache } } +QString Application::getPreviousScriptLocation() { + QString result = _previousScriptLocation.get(); + return result; +} + +void Application::setPreviousScriptLocation(const QString& location) { + _previousScriptLocation.set(location); +} + void Application::loadScriptURLDialog() { auto newScript = OffscreenUi::getText(nullptr, "Open and Run Script", "Script URL"); if (!newScript.isEmpty()) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 71946497d5..e4bfba7492 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -103,6 +103,9 @@ public: void postLambdaEvent(std::function f) override; + QString getPreviousScriptLocation(); + void setPreviousScriptLocation(const QString& previousScriptLocation); + void initializeGL(); void initializeUi(); void paintGL(); @@ -431,6 +434,7 @@ private: Camera _mirrorCamera; // Cammera for mirror view QRect _mirrorViewRect; + Setting::Handle _previousScriptLocation; Setting::Handle _fieldOfView; float _scaleMirror; diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index a261c208d7..df66d1e3e1 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -191,10 +191,10 @@ bool ScriptEditorWidget::save() { bool ScriptEditorWidget::saveAs() { auto scriptEngines = DependencyManager::get(); QString fileName = QFileDialog::getSaveFileName(this, tr("Save script"), - scriptEngines->getPreviousScriptLocation(), + qApp->getPreviousScriptLocation(), tr("JavaScript Files (*.js)")); if (!fileName.isEmpty()) { - scriptEngines->setPreviousScriptLocation(fileName); + qApp->setPreviousScriptLocation(fileName); return saveFile(fileName); } else { return false; diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 919c8b64d3..45a2f3f440 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -87,12 +87,11 @@ void ScriptEditorWindow::loadScriptMenu(const QString& scriptName) { } void ScriptEditorWindow::loadScriptClicked() { - auto scriptEngines = DependencyManager::get(); QString scriptName = QFileDialog::getOpenFileName(this, tr("Interface"), - scriptEngines->getPreviousScriptLocation(), + qApp->getPreviousScriptLocation(), tr("JavaScript Files (*.js)")); if (!scriptName.isEmpty()) { - scriptEngines->setPreviousScriptLocation(scriptName); + qApp->setPreviousScriptLocation(scriptName); addScriptEditorWidget("loading...")->loadFile(scriptName); updateButtons(); } @@ -100,7 +99,7 @@ void ScriptEditorWindow::loadScriptClicked() { void ScriptEditorWindow::loadMenuAboutToShow() { _loadMenu->clear(); - QStringList runningScripts = DependencyManager::get()->getRunningScripts();; + QStringList runningScripts = DependencyManager::get()->getRunningScripts(); if (runningScripts.count() > 0) { QSignalMapper* signalMapper = new QSignalMapper(this); foreach (const QString& runningScript, runningScripts) { diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 0a0b2de47e..6e8469a93f 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -34,8 +34,7 @@ ScriptsModel& getScriptsModel() { } ScriptEngines::ScriptEngines() - : _scriptsLocationHandle("scriptsLocation", DESKTOP_LOCATION), - _previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION) + : _scriptsLocationHandle("scriptsLocation", DESKTOP_LOCATION) { _scriptsModelFilter.setSourceModel(&_scriptsModel); _scriptsModelFilter.sort(0, Qt::AscendingOrder); @@ -445,14 +444,3 @@ void ScriptEngines::onScriptEngineError(const QString& scriptFilename) { qCDebug(scriptengine) << "Application::loadScript(), script failed to load..."; emit scriptLoadError(scriptFilename, ""); } - -QString ScriptEngines::getPreviousScriptLocation() const { - return _previousScriptLocation.get(); -} - -void ScriptEngines::setPreviousScriptLocation(const QString& previousScriptLocation) { - if (_previousScriptLocation.get() != previousScriptLocation) { - _previousScriptLocation.set(previousScriptLocation); - emit previousScriptLocationChanged(); - } -} diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index 97afe9ac57..df60d6ff63 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -30,7 +30,6 @@ class ScriptEngines : public QObject, public Dependency { Q_PROPERTY(ScriptsModel* scriptsModel READ scriptsModel CONSTANT) Q_PROPERTY(ScriptsModelFilter* scriptsModelFilter READ scriptsModelFilter CONSTANT) - Q_PROPERTY(QString previousScriptLocation READ getPreviousScriptLocation WRITE setPreviousScriptLocation NOTIFY previousScriptLocationChanged) public: using ScriptInitializer = std::function; @@ -48,9 +47,6 @@ public: QStringList getRunningScripts(); ScriptEngine* getScriptEngine(const QString& scriptHash); - QString getPreviousScriptLocation() const; - void setPreviousScriptLocation(const QString& previousScriptLocation); - ScriptsModel* scriptsModel() { return &_scriptsModel; }; ScriptsModelFilter* scriptsModelFilter() { return &_scriptsModelFilter; }; @@ -73,7 +69,6 @@ signals: void scriptCountChanged(); void scriptsReloading(); void scriptLoadError(const QString& filename, const QString& error); - void previousScriptLocationChanged(); protected slots: void onScriptFinished(const QString& fileNameString, ScriptEngine* engine); @@ -97,7 +92,6 @@ protected: std::atomic _stoppingAllScripts { false }; std::list _scriptInitializers; mutable Setting::Handle _scriptsLocationHandle; - mutable Setting::Handle _previousScriptLocation; ScriptsModel _scriptsModel; ScriptsModelFilter _scriptsModelFilter; }; From 5b2e739ef3e3d184368af0209e6782c0270f330c Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 16:39:40 -0800 Subject: [PATCH 13/27] Fixing warning --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0bd0031740..14e0ea2a6d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -406,6 +406,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _entityClipboard(new EntityTree()), _lastQueriedTime(usecTimestampNow()), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), + _previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION), _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), _scaleMirror(1.0f), _rotateMirror(0.0f), @@ -416,8 +417,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _aboutToQuit(false), _notifiedPacketVersionMismatchThisDomain(false), _maxOctreePPS(maxOctreePacketsPerSecond.get()), - _lastFaceTrackerUpdate(0), - _previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION) + _lastFaceTrackerUpdate(0) { thread()->setObjectName("Main Thread"); From ab56765ebd4cc297c6af21f0b0f457626126d1fc Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 17:52:22 -0800 Subject: [PATCH 14/27] Add titles to windows --- .../resources/qml/windows/DefaultFrame.qml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/windows/DefaultFrame.qml b/interface/resources/qml/windows/DefaultFrame.qml index fc54a1b1a2..505e653940 100644 --- a/interface/resources/qml/windows/DefaultFrame.qml +++ b/interface/resources/qml/windows/DefaultFrame.qml @@ -20,12 +20,8 @@ Frame { Row { id: controlsRow - anchors.right: parent.right - anchors.top: parent.top - anchors.rightMargin: iconSize - anchors.topMargin: iconSize / 2 + anchors { right: parent.right; top: parent.top; rightMargin: iconSize; topMargin: iconSize / 2; } spacing: iconSize / 4 - FontAwesome { visible: false text: "\uf08d" @@ -54,6 +50,18 @@ Frame { } } } + + Text { + id: titleText + anchors { left: parent.left; leftMargin: iconSize; right: controlsRow.left; rightMargin: iconSize; top: parent.top; topMargin: iconSize / 2; } + text: window.title + elide: Text.ElideRight + font.bold: true + color: window.focus ? "white" : "gray" + style: Text.Outline; + styleColor: "black" + } } + } From afd3ddf534612029cc5f5593a145ccf3676dc3f0 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 21:17:05 -0800 Subject: [PATCH 15/27] Cleaning up message box --- .../resources/qml/dialogs/MessageDialog.qml | 148 +++--------------- .../messageDialog/MessageDialogButton.qml | 12 ++ tests/ui/qmlscratch.pro | 1 + 3 files changed, 33 insertions(+), 128 deletions(-) create mode 100644 interface/resources/qml/dialogs/messageDialog/MessageDialogButton.qml diff --git a/interface/resources/qml/dialogs/MessageDialog.qml b/interface/resources/qml/dialogs/MessageDialog.qml index 35efd4d0d1..ca00da1aa3 100644 --- a/interface/resources/qml/dialogs/MessageDialog.qml +++ b/interface/resources/qml/dialogs/MessageDialog.qml @@ -5,6 +5,7 @@ import QtQuick.Dialogs 1.2 as OriginalDialogs import "../controls" import "../styles" import "../windows" +import "messageDialog" // FIXME respect default button functionality ModalWindow { @@ -126,126 +127,23 @@ ModalWindow { onHeightChanged: d.resize(); onWidthChanged: d.resize(); layoutDirection: Qt.RightToLeft anchors { bottom: details.top; right: parent.right; margins: d.spacing * 2; bottomMargin: 0 } - Button { - id: okButton - text: qsTr("OK") - focus: root.defaultButton === OriginalDialogs.StandardButton.Ok - onClicked: root.click(OriginalDialogs.StandardButton.Ok) - visible: root.buttons & OriginalDialogs.StandardButton.Ok - - } - Button { - id: openButton - text: qsTr("Open") - focus: root.defaultButton === OriginalDialogs.StandardButton.Open - onClicked: root.click(OriginalDialogs.StandardButton.Open) - visible: root.buttons & OriginalDialogs.StandardButton.Open - } - Button { - id: saveButton - text: qsTr("Save") - focus: root.defaultButton === OriginalDialogs.StandardButton.Save - onClicked: root.click(OriginalDialogs.StandardButton.Save) - visible: root.buttons & OriginalDialogs.StandardButton.Save - } - Button { - id: saveAllButton - text: qsTr("Save All") - focus: root.defaultButton === OriginalDialogs.StandardButton.SaveAll - onClicked: root.click(OriginalDialogs.StandardButton.SaveAll) - visible: root.buttons & OriginalDialogs.StandardButton.SaveAll - } - Button { - id: retryButton - text: qsTr("Retry") - focus: root.defaultButton === OriginalDialogs.StandardButton.Retry - onClicked: root.click(OriginalDialogs.StandardButton.Retry) - visible: root.buttons & OriginalDialogs.StandardButton.Retry - } - Button { - id: ignoreButton - text: qsTr("Ignore") - focus: root.defaultButton === OriginalDialogs.StandardButton.Ignore - onClicked: root.click(OriginalDialogs.StandardButton.Ignore) - visible: root.buttons & OriginalDialogs.StandardButton.Ignore - } - Button { - id: applyButton - text: qsTr("Apply") - focus: root.defaultButton === OriginalDialogs.StandardButton.Apply - onClicked: root.click(OriginalDialogs.StandardButton.Apply) - visible: root.buttons & OriginalDialogs.StandardButton.Apply - } - Button { - id: yesButton - text: qsTr("Yes") - focus: root.defaultButton === OriginalDialogs.StandardButton.Yes - onClicked: root.click(OriginalDialogs.StandardButton.Yes) - visible: root.buttons & OriginalDialogs.StandardButton.Yes - } - Button { - id: yesAllButton - text: qsTr("Yes to All") - focus: root.defaultButton === OriginalDialogs.StandardButton.YesToAll - onClicked: root.click(OriginalDialogs.StandardButton.YesToAll) - visible: root.buttons & OriginalDialogs.StandardButton.YesToAll - } - Button { - id: noButton - text: qsTr("No") - focus: root.defaultButton === OriginalDialogs.StandardButton.No - onClicked: root.click(OriginalDialogs.StandardButton.No) - visible: root.buttons & OriginalDialogs.StandardButton.No - } - Button { - id: noAllButton - text: qsTr("No to All") - focus: root.defaultButton === OriginalDialogs.StandardButton.NoToAll - onClicked: root.click(OriginalDialogs.StandardButton.NoToAll) - visible: root.buttons & OriginalDialogs.StandardButton.NoToAll - } - Button { - id: discardButton - text: qsTr("Discard") - focus: root.defaultButton === OriginalDialogs.StandardButton.Discard - onClicked: root.click(OriginalDialogs.StandardButton.Discard) - visible: root.buttons & OriginalDialogs.StandardButton.Discard - } - Button { - id: resetButton - text: qsTr("Reset") - focus: root.defaultButton === OriginalDialogs.StandardButton.Reset - onClicked: root.click(OriginalDialogs.StandardButton.Reset) - visible: root.buttons & OriginalDialogs.StandardButton.Reset - } - Button { - id: restoreDefaultsButton - text: qsTr("Restore Defaults") - focus: root.defaultButton === OriginalDialogs.StandardButton.RestoreDefaults - onClicked: root.click(OriginalDialogs.StandardButton.RestoreDefaults) - visible: root.buttons & OriginalDialogs.StandardButton.RestoreDefaults - } - Button { - id: cancelButton - text: qsTr("Cancel") - focus: root.defaultButton === OriginalDialogs.StandardButton.Cancel - onClicked: root.click(OriginalDialogs.StandardButton.Cancel) - visible: root.buttons & OriginalDialogs.StandardButton.Cancel - } - Button { - id: abortButton - text: qsTr("Abort") - focus: root.defaultButton === OriginalDialogs.StandardButton.Abort - onClicked: root.click(OriginalDialogs.StandardButton.Abort) - visible: root.buttons & OriginalDialogs.StandardButton.Abort - } - Button { - id: closeButton - text: qsTr("Close") - focus: root.defaultButton === OriginalDialogs.StandardButton.Close - onClicked: root.click(OriginalDialogs.StandardButton.Close) - visible: root.buttons & OriginalDialogs.StandardButton.Close - } + MessageDialogButton { dialog: root; text: qsTr("OK"); button: OriginalDialogs.StandardButton.Ok; } + MessageDialogButton { dialog: root; text: qsTr("Open"); button: OriginalDialogs.StandardButton.Open; } + MessageDialogButton { dialog: root; text: qsTr("Save"); button: OriginalDialogs.StandardButton.Save; } + MessageDialogButton { dialog: root; text: qsTr("Save All"); button: OriginalDialogs.StandardButton.SaveAll; } + MessageDialogButton { dialog: root; text: qsTr("Retry"); button: OriginalDialogs.StandardButton.Retry; } + MessageDialogButton { dialog: root; text: qsTr("Ignore"); button: OriginalDialogs.StandardButton.Ignore; } + MessageDialogButton { dialog: root; text: qsTr("Apply"); button: OriginalDialogs.StandardButton.Apply; } + MessageDialogButton { dialog: root; text: qsTr("Yes"); button: OriginalDialogs.StandardButton.Yes; } + MessageDialogButton { dialog: root; text: qsTr("Yes to All"); button: OriginalDialogs.StandardButton.YesToAll; } + MessageDialogButton { dialog: root; text: qsTr("No"); button: OriginalDialogs.StandardButton.No; } + MessageDialogButton { dialog: root; text: qsTr("No to All"); button: OriginalDialogs.StandardButton.NoToAll; } + MessageDialogButton { dialog: root; text: qsTr("Discard"); button: OriginalDialogs.StandardButton.Discard; } + MessageDialogButton { dialog: root; text: qsTr("Reset"); button: OriginalDialogs.StandardButton.Reset; } + MessageDialogButton { dialog: root; text: qsTr("Restore Defaults"); button: OriginalDialogs.StandardButton.RestoreDefaults; } + MessageDialogButton { dialog: root; text: qsTr("Cancel"); button: OriginalDialogs.StandardButton.Cancel; } + MessageDialogButton { dialog: root; text: qsTr("Abort"); button: OriginalDialogs.StandardButton.Abort; } + MessageDialogButton { dialog: root; text: qsTr("Close"); button: OriginalDialogs.StandardButton.Close; } Button { id: moreButton text: qsTr("Show Details...") @@ -253,13 +151,7 @@ ModalWindow { } visible: detailedText && detailedText.length > 0 } - Button { - id: helpButton - text: qsTr("Help") - focus: root.defaultButton === OriginalDialogs.StandardButton.Help - onClicked: root.click(OriginalDialogs.StandardButton.Help) - visible: root.buttons & OriginalDialogs.StandardButton.Help - } + MessageDialogButton { dialog: root; text: qsTr("Help"); button: OriginalDialogs.StandardButton.Help; } } Item { @@ -328,7 +220,7 @@ ModalWindow { case Qt.Key_Enter: case Qt.Key_Return: event.accepted = true - root.click(OriginalDialogs.StandardButton.Ok) + root.click(root.defaultButton) break } } diff --git a/interface/resources/qml/dialogs/messageDialog/MessageDialogButton.qml b/interface/resources/qml/dialogs/messageDialog/MessageDialogButton.qml new file mode 100644 index 0000000000..2bcb3d1f29 --- /dev/null +++ b/interface/resources/qml/dialogs/messageDialog/MessageDialogButton.qml @@ -0,0 +1,12 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 + +Button { + property var dialog; + property int button: StandardButton.NoButton; + + focus: dialog.defaultButton === button + onClicked: dialog.click(button) + visible: dialog.buttons & button +} diff --git a/tests/ui/qmlscratch.pro b/tests/ui/qmlscratch.pro index a4e4b33957..68175382b0 100644 --- a/tests/ui/qmlscratch.pro +++ b/tests/ui/qmlscratch.pro @@ -21,6 +21,7 @@ DISTFILES += \ ../../interface/resources/qml/dialogs/*.qml \ ../../interface/resources/qml/dialogs/fileDialog/*.qml \ ../../interface/resources/qml/dialogs/preferences/*.qml \ + ../../interface/resources/qml/dialogs/messageDialog/*.qml \ ../../interface/resources/qml/desktop/*.qml \ ../../interface/resources/qml/menus/*.qml \ ../../interface/resources/qml/styles/*.qml \ From 35211b7475c2ad7089d0e2c472fbb7b419650fc3 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 21:18:14 -0800 Subject: [PATCH 16/27] Add titles to modal dialogs, move z-order debug display to bottom of window --- interface/resources/qml/windows/Frame.qml | 2 +- interface/resources/qml/windows/ModalFrame.qml | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/windows/Frame.qml b/interface/resources/qml/windows/Frame.qml index cbcf1a77f6..3cbc31fce6 100644 --- a/interface/resources/qml/windows/Frame.qml +++ b/interface/resources/qml/windows/Frame.qml @@ -25,7 +25,7 @@ Item { id: debugZ visible: DebugQML text: window ? "Z: " + window.z : "" - y: -height + y: window.height + 4 } function deltaSize(dx, dy) { diff --git a/interface/resources/qml/windows/ModalFrame.qml b/interface/resources/qml/windows/ModalFrame.qml index 135a27c647..09dbf04b5c 100644 --- a/interface/resources/qml/windows/ModalFrame.qml +++ b/interface/resources/qml/windows/ModalFrame.qml @@ -13,5 +13,16 @@ Frame { color: "#7f7f7f7f"; radius: 3; } + + Text { + y: -implicitHeight - iconSize / 2 + text: window.title + elide: Text.ElideRight + font.bold: true + color: window.focus ? "white" : "gray" + style: Text.Outline; + styleColor: "black" + } + } From c80193635bc694a7628b42a9c9d02ca96cacfa6d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 21:19:21 -0800 Subject: [PATCH 17/27] Update input dialog to support choice selection --- interface/resources/qml/desktop/Desktop.qml | 6 +- .../resources/qml/dialogs/QueryDialog.qml | 25 ++++- libraries/ui/src/OffscreenUi.cpp | 102 +++++++++++++----- libraries/ui/src/OffscreenUi.h | 22 ++-- 4 files changed, 115 insertions(+), 40 deletions(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index b610dbf73c..5bef1cb516 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -252,9 +252,9 @@ FocusScope { return messageDialogBuilder.createObject(desktop, properties); } - Component { id: queryDialogBuilder; QueryDialog { } } - function queryBox(properties) { - return queryDialogBuilder.createObject(desktop, properties); + Component { id: inputDialogBuilder; QueryDialog { } } + function inputDialog(properties) { + return inputDialogBuilder.createObject(desktop, properties); } Component { id: fileDialogBuilder; FileDialog { } } diff --git a/interface/resources/qml/dialogs/QueryDialog.qml b/interface/resources/qml/dialogs/QueryDialog.qml index 52fde34271..159bb95b5d 100644 --- a/interface/resources/qml/dialogs/QueryDialog.qml +++ b/interface/resources/qml/dialogs/QueryDialog.qml @@ -16,9 +16,17 @@ ModalWindow { signal selected(var result); signal canceled(); - property alias result: textResult.text + property var items; + property alias label: mainTextContainer.text + property var result; + // FIXME not current honored + property var current; + + // For text boxes property alias placeholderText: textResult.placeholderText - property alias text: mainTextContainer.text + + // For combo boxes + property bool editable: true; Rectangle { clip: true @@ -55,10 +63,20 @@ ModalWindow { anchors { top: mainTextContainer.bottom; bottom: buttons.top; left: parent.left; right: parent.right; margins: d.spacing } // FIXME make a text field type that can be bound to a history for autocompletion TextField { - focus: true id: textResult + focus: items ? false : true + visible: items ? false : true anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter } } + + VrControls.ComboBox { + id: comboBox + focus: items ? true : false + visible: items ? true : false + anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter } + model: items ? items : [] + } + } Flow { @@ -86,6 +104,7 @@ ModalWindow { text: qsTr("OK") shortcut: Qt.Key_Return onTriggered: { + root.result = items ? comboBox.currentText : textResult.text root.selected(root.result); root.destroy(); } diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index f399cd95a1..8e52507243 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -199,19 +199,7 @@ private slots: } }; -QMessageBox::StandardButton OffscreenUi::messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) { - if (QThread::currentThread() != thread()) { - QMessageBox::StandardButton result = QMessageBox::StandardButton::NoButton; - QMetaObject::invokeMethod(this, "messageBox", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(QMessageBox::StandardButton, result), - Q_ARG(QMessageBox::Icon, icon), - Q_ARG(QString, title), - Q_ARG(QString, text), - Q_ARG(QMessageBox::StandardButtons, buttons), - Q_ARG(QMessageBox::StandardButton, defaultButton)); - return result; - } - +QQuickItem* OffscreenUi::createMessageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) { QVariantMap map; map.insert("title", title); map.insert("text", text); @@ -225,12 +213,34 @@ QMessageBox::StandardButton OffscreenUi::messageBox(QMessageBox::Icon icon, cons if (!invokeResult) { qWarning() << "Failed to create message box"; - return QMessageBox::StandardButton::NoButton; + return nullptr; + } + return qvariant_cast(result); +} + +QMessageBox::StandardButton OffscreenUi::waitForMessageBoxResult(QQuickItem* messageBox) { + if (!messageBox) { + return QMessageBox::NoButton; } - QMessageBox::StandardButton resultButton = MessageBoxListener(qvariant_cast(result)).waitForButtonResult(); - qDebug() << "Message box got a result of " << resultButton; - return resultButton; + return MessageBoxListener(messageBox).waitForButtonResult(); +} + + +QMessageBox::StandardButton OffscreenUi::messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) { + if (QThread::currentThread() != thread()) { + QMessageBox::StandardButton result = QMessageBox::StandardButton::NoButton; + QMetaObject::invokeMethod(this, "messageBox", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(QMessageBox::StandardButton, result), + Q_ARG(QMessageBox::Icon, icon), + Q_ARG(QString, title), + Q_ARG(QString, text), + Q_ARG(QMessageBox::StandardButtons, buttons), + Q_ARG(QMessageBox::StandardButton, defaultButton)); + return result; + } + + return waitForMessageBoxResult(createMessageBox(icon, title, text, buttons, defaultButton)); } QMessageBox::StandardButton OffscreenUi::critical(const QString& title, const QString& text, @@ -273,6 +283,7 @@ private slots: // FIXME many input parameters currently ignored QString OffscreenUi::getText(void* ignored, const QString & title, const QString & label, QLineEdit::EchoMode mode, const QString & text, bool * ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints) { + if (ok) { *ok = false; } QVariant result = DependencyManager::get()->inputDialog(title, label, text).toString(); if (ok && result.isValid()) { *ok = true; @@ -280,35 +291,70 @@ QString OffscreenUi::getText(void* ignored, const QString & title, const QString return result.toString(); } +// FIXME many input parameters currently ignored +QString OffscreenUi::getItem(void *ignored, const QString & title, const QString & label, const QStringList & items, int current, bool editable, bool * ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints) { + if (ok) { + *ok = false; + } -QVariant OffscreenUi::inputDialog(const QString& query, const QString& placeholderText, const QString& currentValue) { + auto offscreenUi = DependencyManager::get(); + auto inputDialog = offscreenUi->createInputDialog(title, label, current); + if (!inputDialog) { + return QString(); + } + inputDialog->setProperty("items", items); + inputDialog->setProperty("editable", editable); + + QVariant result = offscreenUi->waitForInputDialogResult(inputDialog); + if (!result.isValid()) { + return QString(); + } + + if (ok) { + *ok = true; + } + return result.toString(); +} + +QVariant OffscreenUi::inputDialog(const QString& title, const QString& label, const QVariant& current) { if (QThread::currentThread() != thread()) { QVariant result; - QMetaObject::invokeMethod(this, "queryBox", Qt::BlockingQueuedConnection, + QMetaObject::invokeMethod(this, "inputDialog", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, result), - Q_ARG(QString, query), - Q_ARG(QString, placeholderText), - Q_ARG(QString, currentValue)); + Q_ARG(QString, title), + Q_ARG(QString, label), + Q_ARG(QVariant, current)); return result; } + return waitForInputDialogResult(createInputDialog(title, label, current)); +} + + +QQuickItem* OffscreenUi::createInputDialog(const QString& title, const QString& label, const QVariant& current) { QVariantMap map; - map.insert("text", query); - map.insert("placeholderText", placeholderText); - map.insert("result", currentValue); + map.insert("title", title); + map.insert("label", label); + map.insert("current", current); QVariant result; - bool invokeResult = QMetaObject::invokeMethod(_desktop, "queryBox", + bool invokeResult = QMetaObject::invokeMethod(_desktop, "inputDialog", Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, QVariant::fromValue(map))); if (!invokeResult) { qWarning() << "Failed to create message box"; - return QVariant(); + return nullptr; } - return InputDialogListener(qvariant_cast(result)).waitForResult(); + return qvariant_cast(result); } +QVariant OffscreenUi::waitForInputDialogResult(QQuickItem* inputDialog) { + if (!inputDialog) { + return QVariant(); + } + return InputDialogListener(inputDialog).waitForResult(); +} bool OffscreenUi::navigationFocused() { return offscreenFlags->isNavigationFocused(); diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 8ad6641e06..ec5ba433cc 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -42,6 +42,13 @@ public: QQuickItem* getToolWindow(); + // Message box compatibility + Q_INVOKABLE QMessageBox::StandardButton messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton); + // Must be called from the main thread + QQuickItem* createMessageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton); + // Must be called from the main thread + QMessageBox::StandardButton waitForMessageBoxResult(QQuickItem* messageBox); + /// Same design as QMessageBox::critical(), will block, returns result static QMessageBox::StandardButton critical(void* ignored, const QString& title, const QString& text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, @@ -80,18 +87,21 @@ public: QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); - Q_INVOKABLE QMessageBox::StandardButton messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton); - Q_INVOKABLE QVariant inputDialog(const QString& query, const QString& placeholderText = QString(), const QString& currentValue = QString()); + // file dialog compatibility Q_INVOKABLE QString fileOpenDialog(const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); - - // FIXME implement - static QVariant query(const QString& query, const QString& placeholderText = QString(), const QString& currentValue = QString()); - // Compatibility with QFileDialog::getOpenFileName static QString getOpenFileName(void* ignored, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); + + // input dialog compatibility + Q_INVOKABLE QVariant inputDialog(const QString& title, const QString& label = QString(), const QVariant& current = QVariant()); + QQuickItem* createInputDialog(const QString& title, const QString& label, const QVariant& current); + QVariant waitForInputDialogResult(QQuickItem* inputDialog); + // Compatibility with QInputDialog::getText static QString getText(void* ignored, const QString & title, const QString & label, QLineEdit::EchoMode mode = QLineEdit::Normal, const QString & text = QString(), bool * ok = 0, Qt::WindowFlags flags = 0, Qt::InputMethodHints inputMethodHints = Qt::ImhNone); + // Compatibility with QInputDialog::getItem + static QString getItem(void *ignored, const QString & title, const QString & label, const QStringList & items, int current = 0, bool editable = true, bool * ok = 0, Qt::WindowFlags flags = 0, Qt::InputMethodHints inputMethodHints = Qt::ImhNone); private: QQuickItem* _desktop { nullptr }; From 5b1971907c2a6cf438975a0698fc9a25f94ec182 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 28 Jan 2016 21:20:43 -0800 Subject: [PATCH 18/27] Move bookmarks to QML only dialogs --- interface/src/Bookmarks.cpp | 44 +++++++++++++++---------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp index 896a50acca..0a885493e3 100644 --- a/interface/src/Bookmarks.cpp +++ b/interface/src/Bookmarks.cpp @@ -20,12 +20,14 @@ #include #include +#include #include "MainWindow.h" #include "Menu.h" #include "InterfaceLogging.h" #include "Bookmarks.h" +#include Bookmarks::Bookmarks() { _bookmarksFilename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + BOOKMARKS_FILENAME; @@ -104,18 +106,13 @@ void Bookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { } void Bookmarks::bookmarkLocation() { - QInputDialog bookmarkLocationDialog(qApp->getWindow()); - bookmarkLocationDialog.setWindowTitle("Bookmark Location"); - bookmarkLocationDialog.setLabelText("Name:"); - bookmarkLocationDialog.setInputMode(QInputDialog::TextInput); - bookmarkLocationDialog.resize(400, 200); - - if (bookmarkLocationDialog.exec() == QDialog::Rejected) { + bool ok = false; + auto bookmarkName = OffscreenUi::getText(nullptr, "Bookmark Location", "Name:", QLineEdit::Normal, QString(), &ok); + if (!ok) { return; } - QString bookmarkName = bookmarkLocationDialog.textValue().trimmed(); - bookmarkName = bookmarkName.replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " "); + bookmarkName = bookmarkName.trimmed().replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " "); if (bookmarkName.length() == 0) { return; } @@ -125,13 +122,14 @@ void Bookmarks::bookmarkLocation() { Menu* menubar = Menu::getInstance(); if (contains(bookmarkName)) { - QMessageBox duplicateBookmarkMessage; - duplicateBookmarkMessage.setIcon(QMessageBox::Warning); - duplicateBookmarkMessage.setText("The bookmark name you entered already exists in your list."); - duplicateBookmarkMessage.setInformativeText("Would you like to overwrite it?"); - duplicateBookmarkMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - duplicateBookmarkMessage.setDefaultButton(QMessageBox::Yes); - if (duplicateBookmarkMessage.exec() == QMessageBox::No) { + auto offscreenUi = DependencyManager::get(); + auto duplicateBookmarkMessage = offscreenUi->createMessageBox(QMessageBox::Warning, "Duplicate Bookmark", + "The bookmark name you entered already exists in your list.", + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + duplicateBookmarkMessage->setProperty("informativeText", "Would you like to overwrite it?"); + + auto result = offscreenUi->waitForMessageBoxResult(duplicateBookmarkMessage); + if (result != QMessageBox::Yes) { return; } removeLocationFromMenu(menubar, bookmarkName); @@ -157,19 +155,13 @@ void Bookmarks::deleteBookmark() { bookmarkList.append(menuItems[i]->text()); } - QInputDialog deleteBookmarkDialog(qApp->getWindow()); - deleteBookmarkDialog.setWindowTitle("Delete Bookmark"); - deleteBookmarkDialog.setLabelText("Select the bookmark to delete"); - deleteBookmarkDialog.resize(400, 400); - deleteBookmarkDialog.setOption(QInputDialog::UseListViewForComboBoxItems); - deleteBookmarkDialog.setComboBoxItems(bookmarkList); - deleteBookmarkDialog.setOkButtonText("Delete"); - - if (deleteBookmarkDialog.exec() == QDialog::Rejected) { + bool ok = false; + auto bookmarkName = OffscreenUi::getItem(nullptr, "Delete Bookmark", "Select the bookmark to delete", bookmarkList, 0, false, &ok); + if (!ok) { return; } - QString bookmarkName = deleteBookmarkDialog.textValue().trimmed(); + bookmarkName = bookmarkName.trimmed(); if (bookmarkName.length() == 0) { return; } From c4794dd0d551a82f4bdd09ed22f7e577be21b5b2 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 29 Jan 2016 13:41:43 -0800 Subject: [PATCH 19/27] Fix entity properties HTML --- examples/html/entityProperties.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index b9038ccacc..fc585a374e 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -1103,10 +1103,13 @@
B
+
Skybox URL
+
+
From 0e016838b4029e7ceabf00405fe7f7006bd242c8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 10:17:08 -0800 Subject: [PATCH 20/27] tweak size of values in AudioMixer --- assignment-client/src/audio/AudioMixer.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index bcd9478700..d85e1d137b 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -680,11 +680,11 @@ void AudioMixer::domainSettingsRequestComplete() { void AudioMixer::broadcastMixes() { auto nodeList = DependencyManager::get(); - int nextFrame = 0; + int64_t nextFrame = 0; QElapsedTimer timer; timer.start(); - int usecToSleep = AudioConstants::NETWORK_FRAME_USECS; + int64_t usecToSleep = AudioConstants::NETWORK_FRAME_USECS; const int TRAILING_AVERAGE_FRAMES = 100; int framesSinceCutoffEvent = TRAILING_AVERAGE_FRAMES; @@ -826,12 +826,7 @@ void AudioMixer::broadcastMixes() { break; } - usecToSleep = (++nextFrame * AudioConstants::NETWORK_FRAME_USECS) - timer.nsecsElapsed() / 1000; // ns to us - - if (usecToSleep > int(USECS_PER_SECOND)) { - qDebug() << "DANGER: amount to sleep is" << usecToSleep; - qDebug() << "NextFrame is" << nextFrame << "and timer nsecs elapsed is" << timer.nsecsElapsed(); - } + usecToSleep = (++nextFrame * AudioConstants::NETWORK_FRAME_USECS) - (timer.nsecsElapsed() / 1000); if (usecToSleep > 0) { usleep(usecToSleep); From e50e75cba74ce4bdbb2dd77c13efda8f4d1d3f6e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 11:41:23 -0800 Subject: [PATCH 21/27] drop assignment even if DDOS locks NL thread --- libraries/networking/src/NodeList.cpp | 3 +++ libraries/networking/src/NodeList.h | 1 + libraries/networking/src/ThreadedAssignment.cpp | 13 ++++++++++++- libraries/networking/src/ThreadedAssignment.h | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index b0cd8cce39..16277caace 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -490,6 +490,9 @@ void NodeList::processDomainServerList(QSharedPointer message) // this is a packet from the domain server, reset the count of un-replied check-ins _numNoReplyDomainCheckIns = 0; + // emit our signal so listeners know we just heard from the DS + emit receivedDomainServerList(); + DependencyManager::get()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList); QDataStream packetStream(message->getMessage()); diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 171ea0c6a7..4b196d5f7b 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -87,6 +87,7 @@ public slots: signals: void limitOfSilentDomainCheckInsReached(); + void receivedDomainServerList(); private slots: void stopKeepalivePingTimer(); void sendPendingDSPathQuery(); diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 303755c8f3..10f9c03cab 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -30,6 +30,10 @@ ThreadedAssignment::ThreadedAssignment(ReceivedMessage& message) : connect(&_domainServerTimer, &QTimer::timeout, this, &ThreadedAssignment::checkInWithDomainServerOrExit); _domainServerTimer.setInterval(DOMAIN_SERVER_CHECK_IN_MSECS); + + // if the NL tells us we got a DS response, clear our member variable of queued check-ins + auto nodeList = DependencyManager::get(); + connect(nodeList.data(), &NodeList::receivedDomainServerList, this, &ThreadedAssignment::clearQueuedCheckIns); } void ThreadedAssignment::setFinished(bool isFinished) { @@ -103,11 +107,18 @@ void ThreadedAssignment::sendStatsPacket() { } void ThreadedAssignment::checkInWithDomainServerOrExit() { - if (DependencyManager::get()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { + qDebug() << "WE ARE AT" << _numQueuedCheckIns << "queued check-ins"; + + // verify that the number of queued check-ins is not >= our max + // the number of queued check-ins is cleared anytime we get a response from the domain-server + if (_numQueuedCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { setFinished(true); } else { auto nodeList = DependencyManager::get(); QMetaObject::invokeMethod(nodeList.data(), "sendDomainServerCheckIn"); + + // increase the number of queued check ins + _numQueuedCheckIns++; } } diff --git a/libraries/networking/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h index 42d4903c2f..13b9b5bf79 100644 --- a/libraries/networking/src/ThreadedAssignment.h +++ b/libraries/networking/src/ThreadedAssignment.h @@ -33,6 +33,7 @@ public slots: virtual void run() = 0; Q_INVOKABLE virtual void stop() { setFinished(true); } virtual void sendStatsPacket(); + void clearQueuedCheckIns() { _numQueuedCheckIns = 0; } signals: void finished(); @@ -42,6 +43,7 @@ protected: bool _isFinished; QTimer _domainServerTimer; QTimer _statsTimer; + int _numQueuedCheckIns { 0 }; protected slots: void domainSettingsRequestFailed(); From 5551a052617898eb948a2ff9700f1698f3bce5ac Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 11:49:21 -0800 Subject: [PATCH 22/27] removed debug for queued check-ins --- libraries/networking/src/ThreadedAssignment.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 10f9c03cab..4f7ea76b56 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -107,8 +107,6 @@ void ThreadedAssignment::sendStatsPacket() { } void ThreadedAssignment::checkInWithDomainServerOrExit() { - qDebug() << "WE ARE AT" << _numQueuedCheckIns << "queued check-ins"; - // verify that the number of queued check-ins is not >= our max // the number of queued check-ins is cleared anytime we get a response from the domain-server if (_numQueuedCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { From c91f8c7685acd28c516e10afd108a627f1f11a6b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 11:50:13 -0800 Subject: [PATCH 23/27] add debug for DDOS AC drop --- libraries/networking/src/ThreadedAssignment.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 4f7ea76b56..9277aa70cc 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -110,6 +110,8 @@ void ThreadedAssignment::checkInWithDomainServerOrExit() { // verify that the number of queued check-ins is not >= our max // the number of queued check-ins is cleared anytime we get a response from the domain-server if (_numQueuedCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { + qDebug() << "At least" << MAX_SILENT_DOMAIN_SERVER_CHECK_INS << "have been queued without a response from domain-server" + << "Stopping the current assignment"; setFinished(true); } else { auto nodeList = DependencyManager::get(); From 8d17df338bcb90934cf92b39500c7c6739f35ed5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 12:09:39 -0800 Subject: [PATCH 24/27] allow AIM event processing during repeated injection --- libraries/audio/src/AudioInjectorManager.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libraries/audio/src/AudioInjectorManager.cpp b/libraries/audio/src/AudioInjectorManager.cpp index 2327bda0e7..f6f4dc58bf 100644 --- a/libraries/audio/src/AudioInjectorManager.cpp +++ b/libraries/audio/src/AudioInjectorManager.cpp @@ -79,6 +79,11 @@ void AudioInjectorManager::run() { if (_injectors.size() > 0) { // loop through the injectors in the map and send whatever frames need to go out auto front = _injectors.top(); + + // create an InjectorQueue to hold injectors to be queued + // this allows us to call processEvents even if a single injector wants to be re-queued immediately + InjectorQueue holdingQueue; + while (_injectors.size() > 0 && front.first <= usecTimestampNow()) { // either way we're popping this injector off - get a copy first auto injector = front.second; @@ -89,8 +94,8 @@ void AudioInjectorManager::run() { auto nextCallDelta = injector->injectNextFrame(); if (nextCallDelta >= 0 && !injector->isFinished()) { - // re-enqueue the injector with the correct timing - _injectors.emplace(usecTimestampNow() + nextCallDelta, injector); + // enqueue the injector with the correct timing in our holding queue + holdingQueue.emplace(usecTimestampNow() + nextCallDelta, injector); } } @@ -101,6 +106,12 @@ void AudioInjectorManager::run() { break; } } + + // if there are injectors in the holding queue, push them to our persistent queue now + while (!holdingQueue.empty()) { + _injectors.push(holdingQueue.top()); + holdingQueue.pop(); + } } } else { From 20cfe800363984b032e6e6b641f8494dcbd9348e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 27 Jan 2016 15:25:23 -0800 Subject: [PATCH 25/27] use a vector instead of priority queue to avoid double sort --- libraries/audio/src/AudioInjectorManager.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/audio/src/AudioInjectorManager.cpp b/libraries/audio/src/AudioInjectorManager.cpp index f6f4dc58bf..032ad71145 100644 --- a/libraries/audio/src/AudioInjectorManager.cpp +++ b/libraries/audio/src/AudioInjectorManager.cpp @@ -82,7 +82,8 @@ void AudioInjectorManager::run() { // create an InjectorQueue to hold injectors to be queued // this allows us to call processEvents even if a single injector wants to be re-queued immediately - InjectorQueue holdingQueue; + std::vector heldInjectors; + heldInjectors.reserve(_injectors.size()); while (_injectors.size() > 0 && front.first <= usecTimestampNow()) { // either way we're popping this injector off - get a copy first @@ -95,7 +96,7 @@ void AudioInjectorManager::run() { if (nextCallDelta >= 0 && !injector->isFinished()) { // enqueue the injector with the correct timing in our holding queue - holdingQueue.emplace(usecTimestampNow() + nextCallDelta, injector); + heldInjectors.emplace(heldInjectors.end(), usecTimestampNow() + nextCallDelta, injector); } } @@ -108,9 +109,9 @@ void AudioInjectorManager::run() { } // if there are injectors in the holding queue, push them to our persistent queue now - while (!holdingQueue.empty()) { - _injectors.push(holdingQueue.top()); - holdingQueue.pop(); + while (!heldInjectors.empty()) { + _injectors.push(heldInjectors.back()); + heldInjectors.pop_back(); } } From d3028606c5ae844ac8388ecc1f92ec716a476abe Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 29 Jan 2016 14:47:27 -0800 Subject: [PATCH 26/27] retart the nextFrame and frameTimer on injector restart --- libraries/audio/src/AudioInjector.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index ea63df7f17..3bd46833d4 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -102,6 +102,10 @@ void AudioInjector::restart() { // reset the current send offset to zero _currentSendOffset = 0; + // reset the nextFrame and elapsed timer + _nextFrame = 0; + _frameTimer->invalidate(); + // check our state to decide if we need extra handling for the restart request if (_state == State::Finished) { // we finished playing, need to reset state so we can get going again @@ -246,6 +250,11 @@ int64_t AudioInjector::injectNextFrame() { } } + if (!_frameTimer->isValid()) { + // in the case where we have been restarted, the frame timer will be invalid and we need to start it back over here + _frameTimer->restart(); + } + int totalBytesLeftToCopy = (_options.stereo ? 2 : 1) * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL; if (!_options.loop) { // If we aren't looping, let's make sure we don't read past the end From d7990bf88af976a3c9fbe7afe3080988ee5cf5bd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 29 Jan 2016 14:55:08 -0800 Subject: [PATCH 27/27] reset hasSentFirstFrame to false for double frame on first send --- libraries/audio/src/AudioInjector.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 3bd46833d4..157e973f5b 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -102,9 +102,10 @@ void AudioInjector::restart() { // reset the current send offset to zero _currentSendOffset = 0; - // reset the nextFrame and elapsed timer + // reset state to start sending from beginning again _nextFrame = 0; _frameTimer->invalidate(); + _hasSentFirstFrame = false; // check our state to decide if we need extra handling for the restart request if (_state == State::Finished) {