]> www.vanbest.org Git - motioneye-debian/commitdiff
camera controls are set now individually rather than all at once
authorCalin Crisan <ccrisan@gmail.com>
Sat, 11 Jan 2014 15:31:24 +0000 (17:31 +0200)
committerCalin Crisan <ccrisan@gmail.com>
Sat, 11 Jan 2014 16:39:14 +0000 (18:39 +0200)
src/config.py
static/css/main.css
static/css/ui.css
static/js/main.js
templates/main.html

index 3d894be2d48d9741b39bf777a0a1e909c264406e..1bcbcf3ed061ad5932b798a1bdac1752934a09de 100644 (file)
@@ -28,9 +28,7 @@ import v4l2ctl
 
 
 _CAMERA_CONFIG_FILE_NAME = 'thread-%(id)s.conf'
-
-_MAIN_CONFIG_FILE_PATH = os.path.join(settings.CONF_PATH, 'motion.conf')
-_CAMERA_CONFIG_FILE_PATH = os.path.join(settings.CONF_PATH, _CAMERA_CONFIG_FILE_NAME)
+_MAIN_CONFIG_FILE_NAME = 'motion.conf'
 
 _main_config_cache = None
 _camera_config_cache = None
@@ -43,7 +41,7 @@ def get_main(as_lines=False):
     if not as_lines and _main_config_cache is not None:
         return _main_config_cache
     
-    config_file_path = os.path.join(settings.PROJECT_PATH, _MAIN_CONFIG_FILE_PATH)
+    config_file_path = os.path.join(settings.CONF_PATH, _MAIN_CONFIG_FILE_NAME)
     
     logging.debug('reading main config from file %(path)s...' % {'path': config_file_path})
     
@@ -69,7 +67,7 @@ def get_main(as_lines=False):
         
         except Exception as e:
             logging.error('could not read main config file %(path)s: %(msg)s' % {
-                    'path': _MAIN_CONFIG_FILE_PATH, 'msg': unicode(e)})
+                    'path': config_file_path, 'msg': unicode(e)})
             
             raise
         
@@ -92,6 +90,8 @@ def set_main(data):
     
     _set_default_motion(data)
     
+    config_file_path = os.path.join(settings.CONF_PATH, _MAIN_CONFIG_FILE_NAME)
+    
     # read the actual configuration from file
     lines = get_main(as_lines=True)
     
@@ -104,14 +104,14 @@ def set_main(data):
                 threads.append(match.groups()[0])
     
     # write the configuration to file
-    logging.debug('writing main config to %(path)s...' % {'path': _MAIN_CONFIG_FILE_PATH})
+    logging.debug('writing main config to %(path)s...' % {'path': config_file_path})
     
     try:
-        file = open(_MAIN_CONFIG_FILE_PATH, 'w')
+        file = open(config_file_path, 'w')
     
     except Exception as e:
         logging.error('could not open main config file %(path)s for writing: %(msg)s' % {
-                'path': _MAIN_CONFIG_FILE_PATH, 'msg': unicode(e)})
+                'path': config_file_path, 'msg': unicode(e)})
         
         raise
     
@@ -122,7 +122,7 @@ def set_main(data):
     
     except Exception as e:
         logging.error('could not write main config file %(path)s: %(msg)s' % {
-                'path': _MAIN_CONFIG_FILE_PATH, 'msg': unicode(e)})
+                'path': config_file_path, 'msg': unicode(e)})
         
         raise
     
@@ -187,7 +187,7 @@ def get_camera(camera_id, as_lines=False):
     if not as_lines and _camera_config_cache is not None and camera_id in _camera_config_cache:
         return _camera_config_cache[camera_id]
     
-    camera_config_path = _CAMERA_CONFIG_FILE_PATH % {'id': camera_id}
+    camera_config_path = os.path.join(settings.CONF_PATH, _CAMERA_CONFIG_FILE_NAME) % {'id': camera_id}
     
     logging.debug('reading camera config from %(path)s...' % {'path': camera_config_path})
     
@@ -266,7 +266,7 @@ def set_camera(camera_id, data):
                 logging.warn('failed to create target directory: %(msg)s' % {'msg': unicode(e)})
 
     # read the actual configuration from file
-    config_file_path = _CAMERA_CONFIG_FILE_PATH % {'id': camera_id}
+    config_file_path = os.path.join(settings.CONF_PATH, _CAMERA_CONFIG_FILE_NAME) % {'id': camera_id}
     if os.path.isfile(config_file_path):
         lines = get_camera(camera_id, as_lines=True)
     
@@ -274,7 +274,7 @@ def set_camera(camera_id, data):
         lines = []
     
     # write the configuration to file
-    camera_config_path = _CAMERA_CONFIG_FILE_PATH % {'id': camera_id}
+    camera_config_path = os.path.join(settings.CONF_PATH, _CAMERA_CONFIG_FILE_NAME) % {'id': camera_id}
     logging.debug('writing camera config to %(path)s...' % {'path': camera_config_path})
     
     try:
@@ -358,7 +358,7 @@ def rem_camera(camera_id):
     global _camera_config_cache
     
     camera_config_name = _CAMERA_CONFIG_FILE_NAME % {'id': camera_id}
-    camera_config_path = _CAMERA_CONFIG_FILE_PATH % {'id': camera_id}
+    camera_config_path = os.path.join(settings.CONF_PATH, _CAMERA_CONFIG_FILE_NAME) % {'id': camera_id}
     
     # remove the camera from the main config
     main_config = get_main()
index 8471257e372adf111c4cd4b58825dd9fbee218e6..6d14543f236c7b9c232c3e7e93c107e205c2119a 100644 (file)
@@ -176,6 +176,7 @@ div.settings.open {
 }
 
 div.settings-container {
+    position: relative;
     padding-top: 10px;
     display: none;
     white-space: nowrap;
@@ -185,6 +186,17 @@ div.settings.open div.settings-container {
     display: block;
 }
 
+div.settings-progress {
+    position: absolute;
+    top: 0px;
+    width: 0px;
+    bottom: 0px;
+    left: 0px;
+    background-color: #313131;
+    opacity: 0;
+    transition: opacity 0.1s linear;
+}
+
 div.settings-top-bar {
     position: relative;
     display: inline-block;
@@ -197,6 +209,10 @@ div.settings-top-bar.open {
     min-width: 360px;
 }
 
+div.settings-top-bar.closed div.apply-button {
+    display: none !important;
+}
+
 div.settings-section-title {
     position: relative;
     text-align: right;
@@ -261,7 +277,6 @@ div.apply-button {
     background-color: #FF6F00;
     border-radius: 3px;
     transition: all 0.1s linear;
-    transition: opacity 0s;
 }
 
 div.apply-button:HOVER {
index 6b55a69579b34b03c0abb95f17f0c867b2927987..ac5a54fb1ed17d82d71b76a87592a4e4a7b5bf1b 100644 (file)
@@ -1,16 +1,16 @@
 
     /* general */
 
-::selection {
-    background: #3498db;
-}
-
-::-moz-selection {
+::selection,
+::-moz-selection,
+::-webkit-selection {
     background: #3498db;
 }
 
-::-webkit-selection {
-    background: #3498db;
+option::selection,
+option::-moz-selection,
+option::-webkit-selection {
+    background: transparent;
 }
 
 input[type=checkbox].styled {
index c6c95fd722396c1c43ca56ccd6dc0fa74c757e3d..dc383b0c862fb5e0b6ae3e3dcc26d6b7bf1bb6b9 100644 (file)
@@ -3,6 +3,7 @@ var pushConfigs = {};
 var refreshDisabled = 0;
 var fullScreenCameraId = null;
 var thresholdSlider = null;
+var inProgress = false;
 
 
     /* utils */
@@ -250,7 +251,8 @@ function initUI() {
             updateConfigUi();
         }
         else {
-            fetchCurrentCameraConfig();
+            showProgress();
+            fetchCurrentCameraConfig(endProgress);
         }
     });
     $('input.general').change(pushMainConfig);
@@ -265,10 +267,10 @@ function initUI() {
       'input.working-schedule, select.working-schedule').change(pushCameraConfig);
     
     /* preview controls */
-    $('#brightnessSlider').change(pushPreview);
-    $('#contrastSlider').change(pushPreview);
-    $('#saturationSlider').change(pushPreview);
-    $('#hueSlider').change(pushPreview);
+    $('#brightnessSlider').change(function () {pushPreview('brightness');});
+    $('#contrastSlider').change(function () {pushPreview('contrast');});
+    $('#saturationSlider').change(function () {pushPreview('saturation');});
+    $('#hueSlider').change(function () {pushPreview('hue');});
     
     /* apply button */
     $('#applyButton').click(function () {
@@ -295,9 +297,9 @@ function openSettings(cameraId) {
         $('#videoDeviceSelect').val(cameraId).change();
     }
     
-    $('div.settings').addClass('open');
+    $('div.settings').addClass('open').removeClass('closed');
     $('div.page-container').addClass('stretched');
-    $('div.settings-top-bar').addClass('open');
+    $('div.settings-top-bar').addClass('open').removeClass('closed');
     
     updateConfigUi();
 }
@@ -305,9 +307,9 @@ function openSettings(cameraId) {
 function closeSettings() {
     hideApply();
     
-    $('div.settings').removeClass('open');
+    $('div.settings').removeClass('open').addClass('closed');
     $('div.page-container').removeClass('stretched');
-    $('div.settings-top-bar').removeClass('open');
+    $('div.settings-top-bar').removeClass('open').addClass('closed');
 }
 
 function isSettingsOpen() {
@@ -712,59 +714,60 @@ function dict2CameraUi(dict) {
     /* apply button */
 
 function showApply() {
-    if (!$('div.settings-container').is(':visible')) {
-        return; /* settings panel is not open */
-    }
-
     var applyButton = $('#applyButton');
     
     applyButton.html('Apply');
     applyButton.css('display', 'inline-block');
-    applyButton.animate({'opacity': '1'}, 100);
     applyButton.removeClass('progress');
+    setTimeout(function () {
+        applyButton.css('opacity', '1');
+    }, 10);
 }
 
 function showProgress() {
+    if (inProgress) {
+        return; /* already in progress */
+    }
+
+    inProgress = true;
     refreshDisabled++;
     
     /* replace the main page message with a progress indicator */
     $('div.add-camera-message').html('<img class="main-loading-progress" src="' + staticUrl + 'img/main-loading-progress.gif">');
     
-    if (!$('div.settings-container').is(':visible')) {
-        return; /* settings panel is not open */
-    }
-
-    var applyButton = $('#applyButton');
-    
-    if (applyButton.hasClass('progress')) {
-        return; /* progress already visible */
-    }
-    
-    applyButton.html('<img class="apply-progress" src="' + staticUrl + 'img/apply-progress.gif">');
-    applyButton.css('display', 'inline-block');
-    applyButton.animate({'opacity': '1'}, 100);
-    applyButton.addClass('progress');
+    /* show the apply button progress indicator */
+    $('#applyButton').html('<img class="apply-progress" src="' + staticUrl + 'img/apply-progress.gif">');
     
+    /* show the camera progress indicators */
     $('div.camera-progress').css('opacity', '0.5');
+    
+    /* remove the settings progress lock */
+    $('div.settings-progress').css('width', '100%').css('opacity', '0.9');
 }
 
 function hideApply() {
-    if (!$('div.settings-container').is(':visible')) {
-        return; /* settings panel is not open */
-    }
-
     var applyButton = $('#applyButton');
     
-    applyButton.animate({'opacity': '0'}, 100, function () {
-        applyButton.removeClass('progress');
+    applyButton.css('opacity', '0');
+    applyButton.removeClass('progress');
+    
+    setTimeout(function () {
         applyButton.css('display', 'none');
-    });
+    }, 500);
 }
 
 function endProgress() {
+    if (!inProgress) {
+        return; /* not in progress */
+    }
+    
+    inProgress = false;
     refreshDisabled--;
-    $('div.add-camera-message').remove(); /* remove any existing message on the main page */
     
+    /* remove any existing message on the main page */
+    $('div.add-camera-message').remove();
+    
+    /* deal with the apply button */
     if (Object.keys(pushConfigs).length === 0) {
         hideApply();
     }
@@ -772,13 +775,15 @@ function endProgress() {
         showApply();
     }
     
+    /* hide the settings progress lock */
+    $('div.settings-progress').css('opacity', '0');
+    
+    /* hide the camera progress indicator */
     $('div.camera-progress').css('opacity', '0');
-}
 
-function isProgress() {
-    var applyButton = $('#applyButton');
-    
-    return applyButton.hasClass('progress');
+    setTimeout(function () {
+        $('div.settings-progress').css('width', '0px');
+    }, 500);
 }
 
 function isApplyVisible() {
@@ -840,7 +845,7 @@ function doRemCamera() {
 
     var deviceName = $('#videoDeviceSelect').find('option[value=' + cameraId + ']').text();
     
-    runConfirmDialog('Remove device ' + deviceName + '?', function () {
+    runConfirmDialog('Remove camera ' + deviceName + '?', function () {
         showProgress();
         ajax('POST', '/config/' + cameraId + '/rem/', null, function (data) {
             if (data == null || data.error) {
@@ -849,8 +854,7 @@ function doRemCamera() {
                 return;
             }
             
-            endProgress();
-            fetchCurrentConfig();
+            fetchCurrentConfig(endProgress);
         });
     });
 }
@@ -892,13 +896,16 @@ function doUpdate() {
 
     /* fetch & push */
 
-function fetchCurrentConfig() {
+function fetchCurrentConfig(onFetch) {
     function fetchCameraList() {
         /* fetch the camera list */
         ajax('GET', '/config/list/', null, function (data) {
             if (data == null || data.error) {
                 showErrorMessage(data && data.error);
                 data = {cameras: []};
+                if (onFetch) {
+                    onFetch(null);
+                }
             }
             
             var i, cameras = data.cameras;
@@ -933,6 +940,10 @@ function fetchCurrentConfig() {
             else {
                 recreateCameraFrames(cameras);
             }
+
+            if (onFetch) {
+                onFetch(data);
+            }
         });
     }
     
@@ -953,17 +964,23 @@ function fetchCurrentConfig() {
     }
 }
 
-function fetchCurrentCameraConfig() {
+function fetchCurrentCameraConfig(onFetch) {
     var cameraId = $('#videoDeviceSelect').val();
     if (cameraId != null) {
         ajax('GET', '/config/' + cameraId + '/get/', null, function (data) {
             if (data == null || data.error) {
                 showErrorMessage(data && data.error);
                 dict2CameraUi(null);
+                if (onFetch) {
+                    onFetch(null);
+                }
                 return;
             }
             
             dict2CameraUi(data);
+            if (onFetch) {
+                onFetch(data);
+            }
         });
     }
     else {
@@ -990,8 +1007,9 @@ function pushCameraConfig() {
     }
 }
 
-function pushPreview() {
+function pushPreview(control) {
     var cameraId = $('#videoDeviceSelect').val();
+    
     var brightness = $('#brightnessSlider').val();
     var contrast= $('#contrastSlider').val();
     var saturation = $('#saturationSlider').val();
@@ -999,19 +1017,19 @@ function pushPreview() {
     
     var data = {};
     
-    if (brightness !== '') {
+    if (brightness !== '' && (!control || control == 'brightness')) {
         data.brightness = brightness;
     }
     
-    if (contrast !== '') {
+    if (contrast !== '' && (!control || control == 'contrast')) {
         data.contrast = contrast;
     }
     
-    if (saturation !== '') {
+    if (saturation !== '' && (!control || control == 'saturation')) {
         data.saturation = saturation;
     }
     
-    if (hue !== '') {
+    if (hue !== '' && (!control || control == 'hue')) {
         data.hue = hue;
     }
     
@@ -1756,48 +1774,15 @@ function recreateCameraFrames(cameras) {
 
 
 function doConfigureCamera(cameraId) {
-    if (isProgress()) {
+    if (inProgress) {
         return;
     }
     
     openSettings(cameraId);
 }
 
-    /* not used anymore */
-function doCloseCamera(cameraId) {
-    if (isProgress()) {
-        return;
-    }
-    
-    remCameraFrameUi(cameraId);
-    showProgress();
-    ajax('GET', '/config/' + cameraId + '/get/', null, function (data) {
-        if (data == null || data.error) {
-            endProgress();
-            showErrorMessage(data && data.error);
-            return;
-        }
-        
-        data['enabled'] = false;
-        ajax('POST', '/config/' + cameraId + '/set/', data, function (data) {
-            if (data == null || data.error) {
-                showErrorMessage(data && data.error);
-                return;
-            }
-            
-            endProgress();
-            
-            /* if the current camera in the settings panel is the closed camera,
-             * we refresh its settings and update the UI */
-            if ($('#videoDeviceSelect').val() === '' + cameraId) {
-                fetchCurrentCameraConfig();
-            }
-        });
-    });
-}
-
 function doFullScreenCamera(cameraId) {
-    if (isProgress()) {
+    if (inProgress) {
         return;
     }
     
@@ -1947,7 +1932,8 @@ $(document).ready(function () {
     });
     
     initUI();
-    fetchCurrentConfig();
+    showProgress();
+    fetchCurrentConfig(endProgress);
     refreshCameraFrames();
     checkCameraErrors();
 });
index b5abb87533f5832a7da9f6b7ff35b81111e43845..e90128f722bb9bc6c9d733060705faf2e74a36d1 100644 (file)
@@ -16,7 +16,7 @@
     <div class="header">
         <div class="header-container">
             {% if USER == 'admin' %}
-            <div class="settings-top-bar">
+            <div class="settings-top-bar closed">
                 <div class="button settings-button mouse-effect" title="settings"></div>
                 <select class="video-device styled" id="videoDeviceSelect"></select>
                 <div class="button rem-camera-button mouse-effect" id="remCameraButton" title="remove camera"></div>
@@ -33,7 +33,7 @@
     </div>
     <div class="page">
         {% if USER == 'admin' %}
-        <div class="settings">
+        <div class="settings closed">
             <div class="settings-container">
                 <div class="settings-section-title"><input type="checkbox" class="styled section general" id="motionEyeSwitch">General Settings</div>
                 <table class="settings">
                         <td><span class="help-mark" title="sets the working schedule time interval for Sunday">?</span></td>
                     </tr>
                 </table>
+                <div class="settings-progress"></div>
             </div>
         </div>
         <img class="background-logo" src="{{STATIC_URL}}img/motioneye-logo.svg" onmousedown="return false;">