@@ -2854,6 +2854,24 @@ var defaultSettings =
28542854 , actionDown: BI_Hotkey_PlaybackSlower
28552855 , category: "Hotkeys"
28562856 }
2857+ , {
2858+ key: "ui3_hotkey_open_selected_clip"
2859+ , value: "0|0|0|13" // 13: enter
2860+ , hotkey: true
2861+ , label: "Open Selected Clip"
2862+ , hint: "Opens the first clip currently selected in the clip list."
2863+ , actionDown: BI_Hotkey_OpenSelectedClip
2864+ , category: "Hotkeys"
2865+ }
2866+ , { // The order of "close" hotkeys is important, because they suppress each other when one has an effect.
2867+ key: "ui3_hotkey_close_preview_animation"
2868+ , value: "0|0|0|27" // 27: escape
2869+ , hotkey: true
2870+ , label: "Close Clip Preview Animation"
2871+ , hint: "Closes the current clip preview animation"
2872+ , actionDown: BI_Hotkey_CloseClipPreviewAnimation
2873+ , category: "Hotkeys"
2874+ }
28572875 , {
28582876 key: "ui3_hotkey_close_clip"
28592877 , value: "0|0|0|27" // 27: escape
@@ -2872,15 +2890,6 @@ var defaultSettings =
28722890 , actionDown: BI_Hotkey_CloseCamera
28732891 , category: "Hotkeys"
28742892 }
2875- , {
2876- key: "ui3_hotkey_close_preview_animation"
2877- , value: "0|0|0|27" // 27: escape
2878- , hotkey: true
2879- , label: "Close Clip Preview Animation"
2880- , hint: "Closes the current clip preview animation"
2881- , actionDown: BI_Hotkey_CloseClipPreviewAnimation
2882- , category: "Hotkeys"
2883- }
28842893 , {
28852894 key: "ui3_hotkey_preview_animation_up"
28862895 , value: "" // unset
@@ -7022,7 +7031,7 @@ function PtzButtons()
70227031 imgW = imgData.w;
70237032 imgH = imgData.h;
70247033 }
7025- bigThumbHelper.Show($ele, $ele.parent(), self.GetPresetDescription(ele.presetnum), imgUrl, imgW, imgH);
7034+ bigThumbHelper.Show($ele, $ele.parent(), self.GetPresetDescription(ele.presetnum), imgUrl, imgW, imgH, undefined, undefined, undefined, undefined );
70267035 });
70277036 $ele.on("mouseleave touchend touchcancel", function (e)
70287037 {
@@ -12290,9 +12299,11 @@ function BigThumbHelper()
1229012299 var self = this;
1229112300 var $thumb, $desc, $img, img, $canvas, canvas;
1229212301 var isShowing = false;
12302+ var isShowingForRecId = undefined;
1229312303 var initialized = false;
1229412304 var imgCompleteCallback;
1229512305 var imgCompleteUserContext;
12306+ var showTickFlag = null;
1229612307 var Initialize = function ()
1229712308 {
1229812309 if (initialized)
@@ -12332,11 +12343,12 @@ function BigThumbHelper()
1233212343 imgCompleteCallback($img, imgCompleteUserContext, false);
1233312344 }
1233412345 }
12335- this.Show = function ($vAlign, $hAlign, descriptionText, imgSrc, imgW, imgH, imgComplete, userContext, noClear)
12346+ this.Show = function ($vAlign, $hAlign, descriptionText, imgSrc, imgW, imgH, imgComplete, userContext, noClear, recId )
1233612347 {
1233712348 Initialize();
1233812349
1233912350 isShowing = true;
12351+ isShowingForRecId = recId;
1234012352
1234112353 // These callbacks are handled really clumsily such that they won't be called correctly if Show() is called again before the callback from the previous Show().
1234212354 imgCompleteCallback = null;
@@ -12425,19 +12437,37 @@ function BigThumbHelper()
1242512437 else
1242612438 $thumb.css("width", "");
1242712439 $thumb.show();
12440+
12441+ clearTimeout(showTickFlag);
12442+ showTickFlag = setTimeout(function () { showTickFlag = null; }, 0);
1242812443 }
12429- this.Hide = function ()
12444+ /**
12445+ * Hides the big thumbnail tooltip if it is currently showing.
12446+ * @param {String} recId Optional recId of a recording. If provided, the thumbnail will only be hidden if it matches this recording ID.
12447+ */
12448+ this.Hide = function (recId)
1243012449 {
1243112450 if (isShowing)
1243212451 {
12433- isShowing = false;
12434- $thumb.hide();
12452+ if (!recId || recId === isShowingForRecId)
12453+ {
12454+ isShowingForRecId = undefined;
12455+ isShowing = false;
12456+ clearTimeout(showTickFlag);
12457+ $thumb.hide();
12458+ return true;
12459+ }
1243512460 }
12461+ return false;
1243612462 }
1243712463 this.IsShowing = function ()
1243812464 {
1243912465 return isShowing;
1244012466 }
12467+ this.DidShowDuringThisTick = function ()
12468+ {
12469+ return !!showTickFlag;
12470+ }
1244112471}
1244212472///////////////////////////////////////////////////////////////
1244312473// Touch Event Helper /////////////////////////////////////////
@@ -13269,9 +13299,9 @@ function ClipLoader(clipsBodySelector)
1326913299 clipVisibilityMap[clipData.recId] = false;
1327013300 if (!selectedClipsMap[clipData.recId]) // We need clip elements to stick around if they're selected, for the sake of multi-select.
1327113301 $("#c" + clipData.recId).remove();
13272- self.HideBigClipThumb();
13302+ self.HideBigClipThumb(clipData.recId );
1327313303 }
13274- var ClipTileCreateFromId = function (recId)
13304+ this. ClipTileCreateFromId = function (recId)
1327513305 {
1327613306 var $clip = $("#c" + recId);
1327713307 if ($clip.length == 0)
@@ -13334,7 +13364,8 @@ function ClipLoader(clipsBodySelector)
1333413364 $clip.on("mouseleave touchend touchcancel", function (e)
1333513365 {
1333613366 touchEvents.Gate(e);
13337- self.HideBigClipThumb();
13367+ var recId = GetClipIdFromClip($(e.currentTarget));
13368+ self.HideBigClipThumb(recId);
1333813369 });
1333913370
1334013371 clipListContextMenu.AttachContextMenu($clip);
@@ -13384,16 +13415,26 @@ function ClipLoader(clipsBodySelector)
1338413415 }
1338513416 }
1338613417 var timeStr = GetTimeStr(clipData.displayDate);
13387- bigThumbHelper.Show($clip, $clip, camName + " " + timeStr, thumbPath, renderW, renderH);
13418+ bigThumbHelper.Show($clip, $clip, camName + " " + timeStr, thumbPath, renderW, renderH, undefined, undefined, undefined, clipData.recId );
1338813419 if (!clipData.isSnapshot)
1338913420 clipThumbnailVideoPreview.Start($clip, clipData, camName);
1339013421 }
13391- this.HideBigClipThumb = function ()
13422+ /**
13423+ * Hides the big thumbnail tooltip and stops the current clip preview animation.
13424+ * @param {String} recId If provided, the tooltip must match this recId in order to be closed.
13425+ * @returns {Boolean} true if the thumbnail tooltip was closed, false if it was not closed by this function call (it may have already been closed before calling).
13426+ */
13427+ this.HideBigClipThumb = function (recId)
1339213428 {
13393- bigThumbHelper.Hide();
13394- clipThumbnailVideoPreview.Stop();
13429+ var didClose = bigThumbHelper.Hide(recId);
13430+ clipThumbnailVideoPreview.Stop(recId);
13431+ return didClose;
1339513432 }
13396- BindEventsPassive(document, "click", self.HideBigClipThumb);
13433+ BindEventsPassive(document, "click", function ()
13434+ {
13435+ if (!bigThumbHelper.DidShowDuringThisTick()) // I'm unsure if this is check is necessary.
13436+ self.HideBigClipThumb(undefined);
13437+ });
1339713438 this.ScrollToClipObj = function ($clip)
1339813439 {
1339913440 var offset = ($clipsbody.height() / 2) - ($clip.height() / 2);
@@ -13406,7 +13447,7 @@ function ClipLoader(clipsBodySelector)
1340613447 }
1340713448 this.ClipPreviewNavigate = function (offset)
1340813449 {
13409- self.HideBigClipThumb();
13450+ self.HideBigClipThumb(undefined );
1341013451 var lastStartedClipId = clipThumbnailVideoPreview.GetLastStartedClipId();
1341113452 var $clip = null;
1341213453 if (lastStartedClipId)
@@ -13479,7 +13520,7 @@ function ClipLoader(clipsBodySelector)
1347913520 {
1348013521 if (CheckSelectionLimit())
1348113522 return;
13482- ClipTileCreateFromId(range[i]);
13523+ self. ClipTileCreateFromId(range[i]);
1348313524 $("#c" + range[i]).addClass("selected");
1348413525 selectedClips.push(range[i]);
1348513526 selectedClipsMap[range[i]] = true;
@@ -13517,7 +13558,7 @@ function ClipLoader(clipsBodySelector)
1351713558 }
1351813559 else
1351913560 {
13520- self.HideBigClipThumb();
13561+ self.HideBigClipThumb(undefined );
1352113562 self.OpenClip(this, recId, true);
1352213563 }
1352313564 }
@@ -14261,14 +14302,14 @@ function ClipLoader(clipsBodySelector)
1426114302 {
1426214303 var clipIdx = GetClipIndexFromClipId(GetClipIdFromClip($clip));
1426314304 if (clipIdx != -1 && clipIdx + 1 < loadedClipIds.length)
14264- return ClipTileCreateFromId(loadedClipIds[clipIdx + 1]);
14305+ return self. ClipTileCreateFromId(loadedClipIds[clipIdx + 1]);
1426514306 return null;
1426614307 }
1426714308 this.GetClipAboveClip = function ($clip)
1426814309 {
1426914310 var clipIdx = GetClipIndexFromClipId(GetClipIdFromClip($clip));
1427014311 if (clipIdx > 0 && clipIdx - 1 < loadedClipIds.length)
14271- return ClipTileCreateFromId(loadedClipIds[clipIdx - 1]);
14312+ return self. ClipTileCreateFromId(loadedClipIds[clipIdx - 1]);
1427214313 return null;
1427314314 }
1427414315 var GetClipIndexFromClipId = function (recId)
@@ -14502,12 +14543,12 @@ function ClipThumbnailVideoPreview_BruteForce()
1450214543 var clipPreviewStartTimeout = null;
1450314544 var queuedPreview = null;
1450414545 var lastItemId = null;
14505- var lastStartCalledItemId = null;
14546+ var lastStartCalledRecId = null;
1450614547 var averageFrameLoadTime = null;
1450714548
1450814549 this.Start = function ($clip, clipData, camName, frameNum, loopNum)
1450914550 {
14510- lastStartCalledItemId = clipData.recId;
14551+ lastStartCalledRecId = clipData.recId;
1451114552 var duration = clipData.isClip ? clipData.msec : clipData.roughLengthMs;
1451214553 if (settings.ui3_clipPreviewEnabled !== "1" || duration < 500)
1451314554 return;
@@ -14596,14 +14637,17 @@ function ClipThumbnailVideoPreview_BruteForce()
1459614637
1459714638 self.Start($clip, clipData, camName, frameNum, loopNum);
1459814639 }
14599- }, null, true);
14640+ }, null, true, clipData.recId );
1460014641 }
14601- this.Stop = function ()
14642+ this.Stop = function (recId )
1460214643 {
14603- ClearTimeouts();
14604- clipThumbPlaybackActive = false;
14605- bigThumbHelper.Hide();
14606- averageFrameLoadTime = new RollingAverage(self.GetClipPreviewNumFrames());
14644+ if (!recId || lastStartCalledRecId === recId)
14645+ {
14646+ ClearTimeouts();
14647+ clipThumbPlaybackActive = false;
14648+ bigThumbHelper.Hide(lastStartCalledRecId);
14649+ averageFrameLoadTime = new RollingAverage(self.GetClipPreviewNumFrames());
14650+ }
1460714651 }
1460814652 this.GetClipPreviewNumFrames = function ()
1460914653 {
@@ -14615,20 +14659,14 @@ function ClipThumbnailVideoPreview_BruteForce()
1461514659 }
1461614660 this.GetLastStartedClipId = function ()
1461714661 {
14618- return lastStartCalledItemId ;
14662+ return lastStartCalledRecId ;
1461914663 }
1462014664 var ClearTimeouts = function ()
1462114665 {
14622- if (thumbVideoTimeout != null)
14623- {
14624- clearTimeout(thumbVideoTimeout);
14625- thumbVideoTimeout = null;
14626- }
14627- if (clipPreviewStartTimeout != null)
14628- {
14629- clearTimeout(clipPreviewStartTimeout);
14630- clipPreviewStartTimeout = null;
14631- }
14666+ clearTimeout(thumbVideoTimeout);
14667+ thumbVideoTimeout = null;
14668+ clearTimeout(clipPreviewStartTimeout);
14669+ clipPreviewStartTimeout = null;
1463214670 queuedPreview = null;
1463314671 }
1463414672}
@@ -17860,6 +17898,32 @@ function VideoPlayerController()
1786017898 self.Playback_Pause();
1786117899 }
1786217900 }
17901+ this.Playback_FirstSelectedClip = function ()
17902+ {
17903+ if (currentPrimaryTab === "clips")
17904+ {
17905+ var selectedClips = clipLoader.GetAllSelected();
17906+ if (selectedClips.length > 0)
17907+ {
17908+ var recId = selectedClips[0];
17909+ var img = videoPlayer.Loading().image;
17910+ if (!img.isLive && !img.isTimeline() && img.uniqueId === recId)
17911+ {
17912+ if (videoPlayer.Playback_IsPaused())
17913+ videoPlayer.Playback_Play();
17914+ else
17915+ console.log("Playback_FirstSelectedClip had no effect because the selected clip is already playing.");
17916+ return;
17917+ }
17918+ var $clip = clipLoader.ClipTileCreateFromId(recId);
17919+ Playback_ClipObj($clip);
17920+ }
17921+ else
17922+ console.log("Playback_FirstSelectedClip has no effect when a clip is not selected.");
17923+ }
17924+ else
17925+ console.log("Playback_FirstSelectedClip has no effect while not on the Clips tab.");
17926+ }
1786317927 var Playback_ClipObj = function ($clip)
1786417928 {
1786517929 if ($clip != null && $clip.length > 0)
@@ -31930,9 +31994,13 @@ function BI_Hotkey_PlaybackSlower()
3193031994 if (!videoPlayer.Loading().image.isLive)
3193131995 playbackControls.ChangePlaySpeed(-1);
3193231996}
31997+ function BI_Hotkey_OpenSelectedClip()
31998+ {
31999+ videoPlayer.Playback_FirstSelectedClip();
32000+ }
3193332001function BI_Hotkey_CloseClip()
3193432002{
31935- if (suppress_Hotkey_CloseClip )
32003+ if (suppress_Hotkey_CloseThings )
3193632004 return;
3193732005 if (videoPlayer.Loading().image.isTimeline())
3193832006 {
@@ -31943,30 +32011,33 @@ function BI_Hotkey_CloseClip()
3194332011 {
3194432012 clipLoader.CloseCurrentClip();
3194532013 // Prevent this same hotkey event from closing the current camera, too.
31946- clearTimeout(suppress_Hotkey_CloseCamera);
31947- suppress_Hotkey_CloseCamera = setTimeout(function () { suppress_Hotkey_CloseCamera = null; }, 0);
32014+ BI_Suppress_Close_Hotkeys_For_Next_Tick();
3194832015 }
3194932016}
31950- var suppress_Hotkey_CloseClip = null;
31951- var suppress_Hotkey_CloseCamera = null;
32017+ var suppress_Hotkey_CloseThings = null;
32018+ function BI_Suppress_Close_Hotkeys_For_Next_Tick()
32019+ {
32020+ clearTimeout(suppress_Hotkey_CloseThings);
32021+ suppress_Hotkey_CloseThings = setTimeout(function () { suppress_Hotkey_CloseThings = null; }, 0);
32022+ }
3195232023function BI_Hotkey_CloseCamera()
3195332024{
31954- if (suppress_Hotkey_CloseCamera )
32025+ if (suppress_Hotkey_CloseThings )
3195532026 return;
3195632027 var loading = videoPlayer.Loading();
3195732028 if ((loading.image.isLive || videoPlayer.Loading().image.isTimeline()) && !cameraListLoader.CameraIsGroupOrCycle(videoPlayer.Loading().cam))
3195832029 {
3195932030 videoPlayer.ImgClick_Camera(loading.cam);
3196032031 if (videoPlayer.Loading().image.isTimeline())
31961- {
31962- clearTimeout(suppress_Hotkey_CloseClip);
31963- suppress_Hotkey_CloseClip = setTimeout(function () { suppress_Hotkey_CloseClip = null; }, 0);
31964- }
32032+ BI_Suppress_Close_Hotkeys_For_Next_Tick();
3196532033 }
3196632034}
3196732035function BI_Hotkey_CloseClipPreviewAnimation()
3196832036{
31969- clipLoader.HideBigClipThumb();
32037+ if (suppress_Hotkey_CloseThings)
32038+ return;
32039+ if (clipLoader.HideBigClipThumb(undefined))
32040+ BI_Suppress_Close_Hotkeys_For_Next_Tick();
3197032041}
3197132042function BI_Hotkey_ClipPreviewAnimationUp()
3197232043{
0 commit comments