--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="32"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="top-bar-buttons.svg"
+ inkscape:export-filename="/media/data/projects/motioneye/static/img/top-bar-buttons.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="5.1832676"
+ inkscape:cy="-1.5026033"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1027"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-nodes="true"
+ inkscape:bbox-paths="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:object-nodes="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-page="true"
+ inkscape:snap-intersection-paths="true"
+ showguides="true"
+ inkscape:guide-bbox="true" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#3498db;stroke-width:0.84620845000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3752"
+ sodipodi:cx="7.8036885"
+ sodipodi:cy="8.2353296"
+ sodipodi:rx="5.6186557"
+ sodipodi:ry="5.3845448"
+ d="m 13.422344,8.2353296 c 0,2.9738024 -2.515558,5.3845444 -5.6186555,5.3845444 -3.1030978,0 -5.6186557,-2.410742 -5.6186557,-5.3845444 0,-2.973802 2.5155579,-5.3845448 5.6186557,-5.3845448 3.1030975,0 5.6186555,2.4107428 5.6186555,5.3845448 z"
+ transform="matrix(1.1568604,0,0,1.2071587,-1.0277779,1034.4208)" />
+ <path
+ style="fill:none;stroke:#3498db;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 5.5,5.5 5,5"
+ id="path3756"
+ inkscape:connector-curvature="0"
+ transform="translate(0,1036.3622)"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path3758"
+ d="m 10.5,1041.8622 -5,5"
+ style="fill:none;stroke:#3498db;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#3498db;stroke-width:0.84620845000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3792"
+ sodipodi:cx="7.8036885"
+ sodipodi:cy="8.2353296"
+ sodipodi:rx="5.6186557"
+ sodipodi:ry="5.3845448"
+ d="m 13.422344,8.2353296 c 0,2.9738024 -2.515558,5.3845444 -5.6186555,5.3845444 -3.1030978,0 -5.6186557,-2.410742 -5.6186557,-5.3845444 0,-2.973802 2.5155579,-5.3845448 5.6186557,-5.3845448 3.1030975,0 5.6186555,2.4107428 5.6186555,5.3845448 z"
+ transform="matrix(-1.1568604,0,0,1.2071587,33.027778,1034.4209)" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path3794"
+ d="m 21.5,1046.8622 3,-3"
+ style="fill:none;stroke:#3498db;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ style="fill:none;stroke:#3498db;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 24.5,1043.8622 0,-2"
+ id="path3796"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path3798"
+ d="m 24.5,1043.8622 2,0"
+ style="fill:none;stroke:#3498db;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ style="fill:none;stroke:#3498db;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 27.5,1042.8622 -1,1"
+ id="path3800"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path3802"
+ d="m 25.5,1040.8622 -1,1"
+ style="fill:none;stroke:#3498db;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ transform="matrix(1.1568604,0,0,1.2071587,-1.0277779,1054.4208)"
+ d="m 13.422344,8.2353296 c 0,2.9738024 -2.515558,5.3845444 -5.6186555,5.3845444 -3.1030978,0 -5.6186557,-2.410742 -5.6186557,-5.3845444 0,-2.973802 2.5155579,-5.3845448 5.6186557,-5.3845448 3.1030975,0 5.6186555,2.4107428 5.6186555,5.3845448 z"
+ sodipodi:ry="5.3845448"
+ sodipodi:rx="5.6186557"
+ sodipodi:cy="8.2353296"
+ sodipodi:cx="7.8036885"
+ id="path3816"
+ style="fill:none;stroke:#3498db;stroke-width:0.84620845000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path3818"
+ d="m 5.5,1061.8622 5,5"
+ style="fill:none;stroke:#3498db;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ style="fill:none;stroke:#3498db;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 10.5,1061.8622 -5,5"
+ id="path3820"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ transform="matrix(-1.1568604,0,0,1.2071587,33.027778,1054.4209)"
+ d="m 13.422344,8.2353296 c 0,2.9738024 -2.515558,5.3845444 -5.6186555,5.3845444 -3.1030978,0 -5.6186557,-2.410742 -5.6186557,-5.3845444 0,-2.973802 2.5155579,-5.3845448 5.6186557,-5.3845448 3.1030975,0 5.6186555,2.4107428 5.6186555,5.3845448 z"
+ sodipodi:ry="5.3845448"
+ sodipodi:rx="5.6186557"
+ sodipodi:cy="8.2353296"
+ sodipodi:cx="7.8036885"
+ id="path3822"
+ style="fill:none;stroke:#3498db;stroke-width:0.84620845000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ style="fill:none;stroke:#3498db;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 22,1066.3622 2,-2"
+ id="path3824"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path3826"
+ d="m 24,1064.3622 0,-2"
+ style="fill:none;stroke:#3498db;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ style="fill:none;stroke:#3498db;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 24,1064.3622 2,0"
+ id="path3828"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path3830"
+ d="m 27,1063.3622 -1,1"
+ style="fill:none;stroke:#3498db;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ style="fill:none;stroke:#3498db;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 25,1061.3622 -1,1"
+ id="path3832"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="32"
- height="16"
- id="svg2"
- version="1.1"
- inkscape:version="0.48.4 r9939"
- sodipodi:docname="video-buttons.svg"
- inkscape:export-filename="/media/data/projects/motioneye/static/img/validation-error.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1"
- inkscape:cx="39.954578"
- inkscape:cy="-30.616453"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1920"
- inkscape:window-height="1027"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1"
- inkscape:snap-bbox="true"
- inkscape:bbox-nodes="true"
- inkscape:bbox-paths="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:snap-bbox-midpoints="true"
- inkscape:object-paths="true"
- inkscape:object-nodes="true"
- inkscape:snap-smooth-nodes="true"
- inkscape:snap-midpoints="true"
- inkscape:snap-object-midpoints="true"
- inkscape:snap-center="true"
- inkscape:snap-page="true"
- inkscape:snap-intersection-paths="true"
- showguides="true"
- inkscape:guide-bbox="true" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3622)">
- <path
- sodipodi:type="arc"
- style="fill:none;stroke:#000000;stroke-width:0.84620845;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3752"
- sodipodi:cx="7.8036885"
- sodipodi:cy="8.2353296"
- sodipodi:rx="5.6186557"
- sodipodi:ry="5.3845448"
- d="m 13.422344,8.2353296 a 5.6186557,5.3845448 0 1 1 -11.2373112,0 5.6186557,5.3845448 0 1 1 11.2373112,0 z"
- transform="matrix(1.1568604,0,0,1.2071587,-1.0277779,1034.4208)" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 5.5,5.5 5,5"
- id="path3756"
- inkscape:connector-curvature="0"
- transform="translate(0,1036.3622)"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path3758"
- d="m 10.5,1041.8622 -5,5"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
- <path
- sodipodi:type="arc"
- style="fill:none;stroke:#000000;stroke-width:0.84620845;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3792"
- sodipodi:cx="7.8036885"
- sodipodi:cy="8.2353296"
- sodipodi:rx="5.6186557"
- sodipodi:ry="5.3845448"
- d="m 13.422344,8.2353296 a 5.6186557,5.3845448 0 1 1 -11.2373112,0 5.6186557,5.3845448 0 1 1 11.2373112,0 z"
- transform="matrix(-1.1568604,0,0,1.2071587,33.027778,1034.4209)" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path3794"
- d="m 21.5,1046.8622 3,-3"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 24.5,1043.8622 0,-2"
- id="path3796"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path3798"
- d="m 24.5,1043.8622 2,0"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 27.5,1042.8622 -1,1"
- id="path3800"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path3802"
- d="m 25.5,1040.8622 -1,1"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
- <path
- transform="matrix(1.1568604,0,0,1.2071587,-1.0277779,1054.4208)"
- d="m 13.422344,8.2353296 a 5.6186557,5.3845448 0 1 1 -11.2373112,0 5.6186557,5.3845448 0 1 1 11.2373112,0 z"
- sodipodi:ry="5.3845448"
- sodipodi:rx="5.6186557"
- sodipodi:cy="8.2353296"
- sodipodi:cx="7.8036885"
- id="path3816"
- style="fill:none;stroke:#000000;stroke-width:0.84620845;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- sodipodi:type="arc" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path3818"
- d="m 5.5,1061.8622 5,5"
- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
- <path
- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 10.5,1061.8622 -5,5"
- id="path3820"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- transform="matrix(-1.1568604,0,0,1.2071587,33.027778,1054.4209)"
- d="m 13.422344,8.2353296 a 5.6186557,5.3845448 0 1 1 -11.2373112,0 5.6186557,5.3845448 0 1 1 11.2373112,0 z"
- sodipodi:ry="5.3845448"
- sodipodi:rx="5.6186557"
- sodipodi:cy="8.2353296"
- sodipodi:cx="7.8036885"
- id="path3822"
- style="fill:none;stroke:#000000;stroke-width:0.84620845;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- sodipodi:type="arc" />
- <path
- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 22,1066.3622 2,-2"
- id="path3824"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path3826"
- d="m 24,1064.3622 0,-2"
- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 24,1064.3622 2,0"
- id="path3828"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path3830"
- d="m 27,1063.3622 -1,1"
- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 25,1061.3622 -1,1"
- id="path3832"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- </g>
-</svg>
focused-text: #ffffff (100%)
action-text: #3498db
-action-border-unfocused: #2A6C96
+action-border-unfocused: #317CAD
action-border-focused: #3498db
+-> make camera frames positions configurable
+-> hide horrible 404 image on cameras
+-> prevent Request closed errors by stopping mjpg clients before stopping motion
+-> network server storage should only be enabled on special devices (rpi)
-> camera not available background and icon design
-> remove current snapshot GET logs
-> add a motion running status indicator (and maybe a start/stop button)
def _start_motion():
- if not motionctl.running() and len(config.get_enabled_cameras()) > 0:
+ if not motionctl.running() and config.has_enabled_cameras():
motionctl.start()
logging.info('motion started')
return camera_ids
-def get_enabled_cameras():
+def has_enabled_cameras():
+ if not get_main().get('@enabled'):
+ return False
+
camera_ids = get_camera_ids()
cameras = [get_camera(camera_id) for camera_id in camera_ids]
- return [c for c in cameras if c['@enabled']]
+ return bool([c for c in cameras if c['@enabled']])
def get_camera(camera_id, as_lines=False):
data.setdefault('quality', 75)
data.setdefault('@preserve_images', 0)
+ data.setdefault('motion_movies', False)
data.setdefault('ffmpeg_variable_bitrate', 14)
data.setdefault('movie_filename', '')
data.setdefault('ffmpeg_cap_new', False)
finally:
if restart:
- if len(config.get_enabled_cameras()) > 0:
+ if config.has_enabled_cameras():
motionctl.start()
def set_preview(self, camera_id):
div.header-container {
position: relative;
min-width: 320px;
+ min-height: 60px;
width: 100%;
}
float: left;
}
-div.check-box.section div.check-box-button {
- background-color: #515151;
-}
-
-div.check-box.on.section div.check-box-button {
- background-color: #3498db;
-}
-
input[type=text].working-schedule.number {
width: 50px;
}
display: inline-block;
width: 16px;
height: 16px;
- background-image: url(../img/video-buttons.png);
+ background-image: url(../img/top-bar-buttons.png);
margin-left: 3px;
cursor: pointer;
- opacity: 0.7;
- transition: all 0.1s linear;
-}
-
-div.camera-button:HOVER {
opacity: 1;
+ transition: all 0.1s linear;
}
div.camera-button:ACTIVE {
- opacity: 0.5;
+ opacity: 0.6;
}
div.camera-button.close {
}
- /* button */
+ /* buttons */
div.button {
-webkit-user-select: none;
cursor: pointer;
}
+div.button.dialog {
+ display: inline-block;
+ background-color: #414141;
+ min-width: 60px;
+ height: 1.2em;
+ line-height: 1.2em;
+ text-align: center;
+ padding: 0.2em 0.4em;
+ border: 1px solid #317CAD;
+ border-radius: 2px;
+ color: white;
+ transition: all 0.1s linear;
+}
+
+div.button.dialog:FOCUS,
+div.button.dialog:HOVER {
+ border: 1px solid #3498db;
+ background-color: #515151;
+}
+
+div.button.dialog:ACTIVE {
+ background-color: #414141;
+}
+
+div.button.dialog.default {
+ background-color: #317CAD;
+}
+
+div.button.dialog.default:FOCUS,
+div.button.dialog.default:HOVER {
+ background-color: #3498db;
+}
+
+div.button.dialog.default:ACTIVE {
+ background-color: #317CAD;
+}
+
/* check box */
position: relative;
width: 2.5em;
height: 1em;
- border: 1px solid #2A6C96;
+ border: 1px solid #317CAD;
border-radius: 2px;
color: #aaaaaa;
vertical-align: middle;
div.check-box.on div.check-box-button {
left: 50%;
- background-color: #3498db;
+ background-color: #317CAD;
color: white;
}
+div.check-box.on:FOCUS div.check-box-button,
+div.check-box.on:HOVER div.check-box-button {
+ background-color: #3498db;
+}
+
/* input box */
input[type=password].styled,
input[type=text].styled {
width: 90%;
- border: 1px solid #2A6C96;
+ border: 1px solid #317CAD;
border-radius: 2px;
background-color: transparent;
padding: 1px;
-webkit-appearance: none;
appearance: none;
width: 90%;
- border: 1px solid #2A6C96;
+ border: 1px solid #317CAD;
border-radius: 2px;
background-color: transparent;
padding: 1px 1.25em 1px 1px;
}
div.slider-bar-inside {
- border: 1px solid #2A6C96;
+ border: 1px solid #317CAD;
height: 3px;
position: relative;
top: 3px;
}
+ /* modal dialogs */
+
+div.modal-glass {
+ display: none;
+ position: fixed;
+ z-index: 10000;
+ top: 0px;
+ right: 0px;
+ bottom: 0px;
+ left: 0px;
+ background-color: black;
+ opacity: 0;
+}
+
+div.modal-container {
+ position: fixed;
+ display: none;
+ z-index: 10001;
+ background-color: #313131;
+ border-radius: 3px;
+ opacity: 0;
+ padding: 5px;
+ box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
+}
+
+div.modal-title-bar {
+ height: 1.5em;
+ line-height: 1.5em;
+ text-align: center;
+ position: relative;
+}
+
+span.modal-title {
+ color: white;
+}
+
+div.modal-close-button {
+ position: absolute;
+ top: 0.3em;
+ right: 0.3em;
+ width: 16px;
+ height: 16px;
+ background-image: url(../img/top-bar-buttons.png);
+ opacity: 1;
+ transition: all 0.1s linear;
+ cursor: pointer;
+}
+
+div.modal-close-button:ACTIVE {
+ opacity: 0.6;
+}
+
+table.modal-buttons-container {
+ width: 100%;
+ text-align: center;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+
+table.modal-buttons-container td:not(:FIRST-CHILD) {
+ padding-left: 5px;
+}
+
+table.modal-buttons-container div.button.dialog {
+ display: block;
+}
+
+
/* misc */
span.help-mark {
};
- /* UI */
+ /* UI initialization */
function initUI() {
/* checkboxes */
doApply();
});
+
+ /* whenever the window is resized,
+ * if a modal dialog is visible, it should be repositioned */
+ $(window).resize(updateModalDialogPosition);
}
/* fetch the main configuration */
ajax('GET', '/config/main/get/', null, function (data) {
dict2MainUi(data);
- });
-
- /* fetch the camera list */
- ajax('GET', '/config/list/', null, function (data) {
- var i, cameras = data.cameras;
- var videoDeviceSelect = $('#videoDeviceSelect');
- videoDeviceSelect.html('');
- for (i = 0; i < cameras.length; i++) {
- var camera = cameras[i];
- videoDeviceSelect.append('<option value="' + camera['id'] + '">' + camera['name'] + '</option>');
- }
-
- if (cameras.length) {
- videoDeviceSelect[0].selectedIndex = 0;
- fetchCurrentCameraConfig();
- }
-
- recreateCameraFrames(cameras);
+
+ /* fetch the camera list */
+ ajax('GET', '/config/list/', null, function (data) {
+ var i, cameras = data.cameras;
+ var videoDeviceSelect = $('#videoDeviceSelect');
+ videoDeviceSelect.html('');
+ for (i = 0; i < cameras.length; i++) {
+ var camera = cameras[i];
+ videoDeviceSelect.append('<option value="' + camera['id'] + '">' + camera['name'] + '</option>');
+ }
+
+ if (cameras.length) {
+ videoDeviceSelect[0].selectedIndex = 0;
+ fetchCurrentCameraConfig();
+ }
+
+ recreateCameraFrames(cameras);
+ });
});
}
}
function recreateCameraFrames(cameras) {
+ /* if motioneye is globally disabled, we remove all the camera frames */;
+ if (!$('#motionEyeSwitch')[0].checked) {
+ cameras = [];
+ }
+
var pageContainer = $('div.page-container');
function updateCameras(cameras) {
+
+ /* UI widgets */
+
function makeCheckBox($input) {
var mainDiv = $('<div class="check-box"></div>');
var buttonDiv = $('<div class="check-box-button"></div>');
return slider;
}
+
+ /* validators */
+
function makeTextValidator($input, required) {
if (required == null) {
required = true;
$input.addClass('time-validator');
$input[0].validate = validate;
}
+
+
+ /* modal dialog */
+
+function showModalDialog(content, onClose) {
+ var glass = $('div.modal-glass');
+ var container = $('div.modal-container');
+
+ glass.css('display', 'block');
+ glass.animate({'opacity': '0.7'}, 200);
+
+ container[0]._onClose = onClose; /* remember the onClose handler */
+ container.html(content);
+
+ container.css('display', 'block');
+ updateModalDialogPosition();
+ container.animate({'opacity': '1'}, 200);
+}
+
+function hideModalDialog() {
+ var glass = $('div.modal-glass');
+ var container = $('div.modal-container');
+
+ glass.animate({'opacity': '0'}, 200, function () {
+ glass.css('display', 'none');
+ });
+
+ container.animate({'opacity': '0'}, 200, function () {
+ container.css('display', 'none');
+ container.html('');
+ });
+
+ /* run the onClose handler, if supplied */
+ if (container[0]._onClose) {
+ container[0]._onClose();
+ }
+}
+
+function updateModalDialogPosition() {
+ var container = $('div.modal-container');
+ if (!container.is(':visible')) {
+ return;
+ }
+
+ var windowWidth = $(window).width();
+ var windowHeight = $(window).height();
+ var modalWidth = container.width();
+ var modalHeight = container.width();
+
+ container.css('left', (windowWidth - modalWidth) / 2);
+ container.css('top', (windowHeight - modalHeight) / 2);
+}
+
+function makeModalDialogButtons(buttonsInfo) {
+ /* buttonsInfo is an array of:
+ * * caption: String
+ * * isDefault: Boolean
+ * * click: Function
+ */
+
+ var buttonsContainer = $('<table class="modal-buttons-container"><tr></tr></table>');
+ var tr = buttonsContainer.find('tr');
+
+ buttonsInfo.forEach(function (info) {
+ var buttonDiv = $('<div class="button dialog"></div>');
+
+ buttonDiv.click(hideModalDialog); /* every button closes the dialog */
+ buttonDiv.attr('tabIndex', '0'); /* make button focusable */
+ buttonDiv.html(info.caption);
+
+ if (info.isDefault) {
+ buttonDiv.addClass('default');
+ }
+
+ if (info.click) {
+ buttonDiv.click(info.click);
+ }
+
+ var td = $('<td></td>');
+ td.append(buttonDiv);
+ tr.append(td);
+ });
+
+ return buttonsContainer;
+}
+
+function makeModalDialogTitleBar(options) {
+ /* available options:
+ * * title: String
+ * * closeButton: Boolean
+ */
+
+ var titleBar = $('<div class="modal-title-bar"></div>');
+
+ var titleSpan = $('<span class="modal-title"></span>');
+ titleSpan.html(options.title || '');
+
+ titleBar.append(titleSpan);
+
+ if (options.closeButton) {
+ var closeButton = $('<div class="modal-close-button" title="close"></div>');
+ closeButton.click(hideModalDialog);
+ titleBar.append(closeButton);
+ }
+
+ return titleBar;
+}
+
+function runModalDialog(options) {
+ /* available options:
+ * * title: String
+ * * closeButton: Boolean
+ * * content: any
+ * * buttons: 'yesno'|'okcancel'|Array
+ * * onYes: Function
+ * * onNo: Function
+ * * onOk: Function
+ * * onCancel: Function
+ * * onClose: Function
+ */
+
+ var content = $('<div></div>');
+ var titleBar = null;
+ var buttonsDiv = null;
+ var defaultClick = null;
+
+ /* add title bar */
+ if (options.title) {
+ titleBar = makeModalDialogTitleBar({title: options.title, closeButton: options.closeButton});
+ content.append(titleBar);
+ }
+
+ /* add supplied content */
+ if (options.content) {
+ content.append(options.content);
+ }
+
+ /* add buttons */
+ if (options.buttons === 'yesno') {
+ options.buttons = [
+ {caption: 'No', click: options.onNo},
+ {caption: 'Yes', isDefault: true, click: options.onYes}
+ ];
+ }
+ else if (options.buttons === 'okcancel') {
+ options.buttons = [
+ {caption: 'Cancel', click: options.onCancel},
+ {caption: 'OK', isDefault: true, click: options.onOk}
+ ];
+ }
+
+ if (options.buttons) {
+ buttonsDiv = makeModalDialogButtons(options.buttons);
+ content.append(buttonsDiv);
+
+ options.buttons.forEach(function (info) {
+ if (info.isDefault) {
+ defaultClick = info.click;
+ }
+ });
+ }
+
+ if ((buttonsDiv || options.content) && titleBar) {
+ titleBar.css('margin-bottom', '5px');
+ }
+
+ var handleKeyUp = function (e) {
+ switch (e.which) {
+ case 13:
+ if (defaultClick) {
+ defaultClick();
+ }
+ /* intentionally no break */
+
+ case 27:
+ hideModalDialog();
+ }
+ };
+
+ var onClose = function () {
+ if (options.onClose) {
+ options.onClose();
+ }
+
+ /* unbind html handlers */
+
+ $('html').unbind('keyup', handleKeyUp);
+ };
+
+ /* bind key handlers */
+ $('html').bind('keyup', handleKeyUp);
+
+ /* and finally, show the dialog */
+ showModalDialog(content, onClose);
+
+ /* focus the default button if nothing else is focused */
+ if (content.find('*:focus').length === 0) {
+ content.find('div.button.default').focus();
+ }
+}
<option value="180">180°</option>
<option value="270">270°</option>
</select>
- <td><span class="help-mark" title="use this to rotate the captured image, if your camera is not positioned correctly">?</span></td>
</td>
+ <td><span class="help-mark" title="use this to rotate the captured image, if your camera is not positioned correctly">?</span></td>
</tr>
<tr class="settings-item advanced-setting">
<td class="settings-item-label"><span class="settings-item-label">Frame Rate</span></td>
copyright © Calin Crisan 2013
</div>
</div>
+ <div class="modal-glass"></div>
+ <div class="modal-container"></div>
{% endblock %}