From e82f80b46ada10cd83f2e0faf28a2281a27ec533 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Tue, 6 Dec 2016 10:24:53 -0500 Subject: multiple montage profile support added #390 --- www/css/style.css | 4 + www/external/origjs/packery.pkgd.js | 4 +- www/external/packery.pkgd.min.js | 2 +- www/js/DataModel.js | 9 ++ www/js/MontageCtrl.js | 232 +++++++++++++++++++++++++++++++----- www/lang/locale-en.json | 4 + www/templates/montage.html | 45 ++++++- 7 files changed, 261 insertions(+), 39 deletions(-) (limited to 'www') diff --git a/www/css/style.css b/www/css/style.css index 1ff3ce8c..2b3fda9b 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -26,6 +26,10 @@ background-size:contain; } +.icon-save:before { + font-family: "fontawesome"; + content: "\f0c7"; +} diff --git a/www/external/origjs/packery.pkgd.js b/www/external/origjs/packery.pkgd.js index 7576576b..fa4e8308 100644 --- a/www/external/origjs/packery.pkgd.js +++ b/www/external/origjs/packery.pkgd.js @@ -3088,10 +3088,10 @@ proto._bindFitEvents = function( item ) { // -------------------------- resize -------------------------- // // debounced, layout on resize -proto.resize = function() { +proto.resize = function(force) { // don't trigger if size did not change // or if resize was unbound. See #285, outlayer#9 - if ( !this.isResizeBound || !this.needsResizeLayout() ) { + if ( !force && (!this.isResizeBound || !this.needsResizeLayout()) ) { return; } diff --git a/www/external/packery.pkgd.min.js b/www/external/packery.pkgd.min.js index f1ba5e03..0a072330 100644 --- a/www/external/packery.pkgd.min.js +++ b/www/external/packery.pkgd.min.js @@ -227,7 +227,7 @@ else{var o=this._getElementOffset(t) e=new i({x:this._getOption("originLeft")?o.left:o.right,y:this._getOption("originTop")?o.top:o.bottom})}this._setRectSize(t,e),this.packer.placed(e),this._setMaxXY(e)},u.sortItemsByPosition=function(){var t=this._getOption("horizontal")?r:s this.items.sort(t)},u.fit=function(t,e,i){var n=this.getItem(t) n&&(this.stamp(n.element),n.enablePlacing(),this.updateShiftTargets(n),e=void 0===e?n.rect.x:e,i=void 0===i?n.rect.y:i,this.shift(n,e,i),this._bindFitEvents(n),n.moveTo(n.rect.x,n.rect.y),this.shiftLayout(),this.unstamp(n.element),this.sortItemsByPosition(),n.disablePlacing())},u._bindFitEvents=function(t){function e(){n++,2==n&&i.dispatchEvent("fitComplete",null,[t])}var i=this,n=0 -t.once("layout",e),this.once("layoutComplete",e)},u.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&(this.options.shiftPercentResize?this.resizeShiftPercentLayout():this.layout())},u.needsResizeLayout=function(){var e=t(this.element),i=this._getOption("horizontal")?"innerHeight":"innerWidth" +t.once("layout",e),this.once("layoutComplete",e)},u.resize=function(t){(t||this.isResizeBound&&this.needsResizeLayout())&&(this.options.shiftPercentResize?this.resizeShiftPercentLayout():this.layout())},u.needsResizeLayout=function(){var e=t(this.element),i=this._getOption("horizontal")?"innerHeight":"innerWidth" return e[i]!=this.size[i]},u.resizeShiftPercentLayout=function(){var e=this._getItemsForLayout(this.items),i=this._getOption("horizontal"),n=i?"y":"x",o=i?"height":"width",s=i?"rowHeight":"columnWidth",r=i?"innerHeight":"innerWidth",a=this[s] if(a=a&&a+this.gutter){this._getMeasurements() var h=this[s]+this.gutter diff --git a/www/js/DataModel.js b/www/js/DataModel.js index 5a837039..4c8be1a7 100644 --- a/www/js/DataModel.js +++ b/www/js/DataModel.js @@ -121,6 +121,7 @@ angular.module('zmApp.controllers') 'enableBlog': true, 'use24hr': false, 'packeryPositions': '', + 'packeryPositionsArray': {}, 'EHpackeryPositions': '', 'packerySizes': '', 'timelineModalGraphType': 'all', @@ -755,6 +756,14 @@ angular.module('zmApp.controllers') } + if (typeof loginData.packeryPositionsArray == 'undefined') + { + debug("packeryPositionsArray does not exist. Setting to empty"); + loginData.packeryPositionsArray = {}; + + } + + if (typeof loginData.packeryPositions == 'undefined') { debug("packeryPositions does not exist. Setting to empty"); diff --git a/www/js/MontageCtrl.js b/www/js/MontageCtrl.js index 294073f5..ffb265cf 100644 --- a/www/js/MontageCtrl.js +++ b/www/js/MontageCtrl.js @@ -4,7 +4,7 @@ /* global cordova,StatusBar,angular,console,ionic,Packery, Draggabilly, imagesLoaded, ConnectSDK, moment */ angular.module('zmApp.controllers') - .controller('zmApp.MontageCtrl', ['$scope', '$rootScope', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$ionicPopup', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', 'zm', '$ionicPopover', '$controller', 'imageLoadingDataShare', '$window', '$localstorage', '$translate', function($scope, $rootScope, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $ionicPopup, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, zm, $ionicPopover, $controller, imageLoadingDataShare, $window, $localstorage, $translate) + .controller('zmApp.MontageCtrl', ['$scope', '$rootScope', 'NVRDataModel', 'message', '$ionicSideMenuDelegate', '$timeout', '$interval', '$ionicModal', '$ionicLoading', '$http', '$state', '$ionicPopup', '$stateParams', '$ionicHistory', '$ionicScrollDelegate', '$ionicPlatform', 'zm', '$ionicPopover', '$controller', 'imageLoadingDataShare', '$window', '$localstorage', '$translate', 'SecuredPopups', function($scope, $rootScope, NVRDataModel, message, $ionicSideMenuDelegate, $timeout, $interval, $ionicModal, $ionicLoading, $http, $state, $ionicPopup, $stateParams, $ionicHistory, $ionicScrollDelegate, $ionicPlatform, zm, $ionicPopover, $controller, imageLoadingDataShare, $window, $localstorage, $translate, SecuredPopups) { //--------------------------------------------------------------------- @@ -175,7 +175,7 @@ angular.module('zmApp.controllers') columnWidth: '.grid-sizer', gutter: 0, initLayout: layouttype, - shiftPercentResize:true + shiftPercentResize: true }); @@ -186,9 +186,12 @@ angular.module('zmApp.controllers') NVRDataModel.debug('~~loaded image is ' + result + ' for ' + img.img.src); // lay out every image if a pre-arranged position has not been found - - $timeout (function(){if (layouttype) pckry.layout();},100); - + + $timeout(function() + { + if (layouttype) pckry.layout(); + }, 100); + progressCalled = true; // if (layouttype) $timeout (function(){layout(pckry);},100); @@ -207,7 +210,7 @@ angular.module('zmApp.controllers') if (!progressCalled) { NVRDataModel.log("*** PROGRESS WAS NOT CALLED"); - // pckry.reloadItems(); + // pckry.reloadItems(); } $timeout(function() @@ -250,14 +253,15 @@ angular.module('zmApp.controllers') { //NVRDataModel.log("Force calling resize"); ///pckry.reloadItems(); - pckry.initShiftLayout(positions,"data-item-id"); + pckry.initShiftLayout(positions, "data-item-id"); // now do a jiggle $timeout(function() { - pckry.shiftLayout(); + NVRDataModel.debug("doing the jiggle and dance..."); + pckry.resize(true); }, 300); - }, 20); + }, 100); //pckry.onresize(); @@ -919,28 +923,189 @@ angular.module('zmApp.controllers') function orientationChanged() { - /*NVRDataModel.debug("Detected orientation change, redoing packery resize"); - - $timeout(function () { - var positions = pckry.getShiftPositions('data-item-id'); - pckry.initShiftLayout(positions,'data-item-id'); - pckry.shiftLayout(); - }, zm.packeryTimer);*/ - - /* var positions = pckry.getShiftPositions('data-item-id'); - $timeout(function () { - NVRDataModel.log("init shift layout"); - pckry.initShiftLayout(positions,"data-item-id"); - $ionicScrollDelegate.$getByHandle("montage-delegate").scrollTop(); - }, 20);*/ - - //console.log ("POSITIONS MAP " + JSON.stringify(positions)); - // var ld = NVRDataModel.getLogin(); - // ld.packeryPositions = JSON.stringify(positions); - //console.log ("Saving " + ld.packeryPositions); - // NVRDataModel.setLogin(ld); + } + + // remove a saved montage profile + $scope.deleteMontageProfile = function() + { + var posArray; + + try + { + posArray = NVRDataModel.getLogin().packeryPositionsArray; + //console.log ("PA="+JSON.stringify(posArray)); + + } + catch (e) + { + NVRDataModel.debug("error parsing packery array positions"); + posArray = {}; + } + + //console.log ("posArray="+JSON.stringify(posArray)); + + $scope.listdata = []; + for (var key in posArray) + { + if (posArray.hasOwnProperty(key)) + { + $scope.listdata.push(key); + } + } + + if (!$scope.listdata.length) + { + + $rootScope.zmPopup = $ionicPopup.alert( + { + title: $translate.instant('kError'), + template: $translate.instant('kMontageNoSavedProfiles') + }); + return; + } + + $scope.data = { + 'selectedVal': '' + }; + + $rootScope.zmPopup = SecuredPopups.show('confirm', + { + template: ' ' + + ' ' + + ' {{item}} ' + + ' ' + + ' ', + + title: $translate.instant('kSelect'), + scope: $scope, + + }).then(function(res) + { + NVRDataModel.debug("Deleting profile: " + $scope.data.selectedVal); + delete posArray[$scope.data.selectedVal]; + var ld = NVRDataModel.getLogin(); + ld.packeryPositionsArray = posArray; + NVRDataModel.setLogin(ld); + + }); + + }; + + // switch to another montage profile + $scope.switchMontageProfile = function() + { + var posArray; + + try + { + posArray = NVRDataModel.getLogin().packeryPositionsArray; + //console.log ("PA="+JSON.stringify(posArray)); + + } + catch (e) + { + NVRDataModel.debug("error parsing packery array positions"); + posArray = {}; + } + + //console.log ("posArray="+JSON.stringify(posArray)); + + $scope.listdata = []; + for (var key in posArray) + { + if (posArray.hasOwnProperty(key)) + { + $scope.listdata.push(key); + } + } + + if (!$scope.listdata.length) + { + + $rootScope.zmPopup = $ionicPopup.alert( + { + title: $translate.instant('kError'), + template: $translate.instant('kMontageNoSavedProfiles') + }); + return; + } + + $scope.data = { + 'selectedVal': '' + }; + + $rootScope.zmPopup = SecuredPopups.show('confirm', + { + template: ' ' + + ' ' + + ' {{item}} ' + + ' ' + + ' ', + + title: $translate.instant('kSelect'), + scope: $scope, + + }).then(function(res) + { + if (res) + { + //console.log ("SELECTED " + $scope.data.selectedVal); + var ld = NVRDataModel.getLogin(); + //console.log ("OLD POS="+ld.packeryPositions); + ld.packeryPositions = ld.packeryPositionsArray[$scope.data.selectedVal]; + //console.log ("NEW POS="+ld.packeryPositions); + NVRDataModel.setLogin(ld); + NVRDataModel.reloadMonitorDisplayStatus(); + draggies.forEach(function(drag) + { + drag.destroy(); + }); + draggies = []; + pckry.destroy(); + initPackery(); + //pckry.reloadItems(); + } + + }); + + }; + + // save current configuration into a profile + $scope.saveMontageProfile = function() + { + $scope.data = { + montageName: "" + }; + $rootScope.zmPopup = SecuredPopups.show('confirm', + { + title: $translate.instant('kMontageSave'), + template: "", + subTitle: $translate.instant('kMontageSaveSubtitle'), + scope: $scope, + + }).then(function(res) + { + console.log(res); + if (res) // ok + { + + var ld = NVRDataModel.getLogin(); + + if ($scope.data.montageName != '') + { + var pos = JSON.stringify(pckry.getShiftPositions('data-item-id')); + ld.packeryPositionsArray[$scope.data.montageName] = pos; + NVRDataModel.debug("Saving " + $scope.data.montageName + " with:" + pos); + NVRDataModel.setLogin(ld); + } + + } + }); + + }; + $scope.toggleSizeButtons = function() { @@ -1196,10 +1361,15 @@ angular.module('zmApp.controllers') ld.packeryPositions = JSON.stringify(positions); //console.log ("Saving " + ld.packeryPositions); NVRDataModel.setLogin(ld); + + $timeout(function() + { + NVRDataModel.debug("doing the jiggle and dance..."); + pckry.resize(true); + }, 300); + // $scope.slider.monsize = 2; }); - //layout(pckry); - pckry.layout(); }, 20); diff --git a/www/lang/locale-en.json b/www/lang/locale-en.json index 951edb38..33ecc8a8 100644 --- a/www/lang/locale-en.json +++ b/www/lang/locale-en.json @@ -203,6 +203,9 @@ "kMonitors" :"Monitors", "kMontage" :"Montage", "kMontageImageScale" :"Montage image scale", + "kMontageNoSavedProfiles" :"No saved montage profiles", + "kMontageSave" :"Save Montage Profile", + "kMontageSaveSubtitle" :"please enter a profile name to save current settings", "kMonth" :"Month", "kMore" :"more", "kNeedToKnow" :"I need to know your ZoneMinder login and path details to get started", @@ -284,6 +287,7 @@ "kSearch" :"search", "kSearchCancelled" :"search cancelled", "kSec" :"sec", + "kSelect" :"Please Select", "kSelectFallback" :"Select fallback", "kSelectLanguage" :"Select Language", "kSelectRunState" :"Select run state", diff --git a/www/templates/montage.html b/www/templates/montage.html index ceab34ae..3bb62104 100644 --- a/www/templates/montage.html +++ b/www/templates/montage.html @@ -3,7 +3,7 @@ - @@ -23,14 +23,49 @@ - +
+
+
+
    +
  • + +
  • +
  • + +
  • +
+
+ +
+
    +
  • + +
  • + +
  • + +
  • + +
  • + +
  • + + +
+
+
+ + +
-
- +
-- cgit v1.2.3