Commit 3c834323 authored by Andrey Filippov's avatar Andrey Filippov

Initial release - cloned from NC353 camera

parent 32e1d442
html/*
attic/*
/.project
/.cproject
/.pydevproject
/.externalToolBuilders
/.settings
.directory
generated*
sysroots
bitbake-logs
/temp/
#!/bin/bash
args="$@"
while (( "$#" )); do
shift
done
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo "Launching bitbake $args"
cd $DIR/../../poky
. ./oe-init-build-env
bitbake $args | sed -u 's@| @@'
exit 0
# -----------------------------------------------------------------------------**
# packages/web/353/Makefile
#
# Copyright (C) 2005-2008 Elphel, Inc.
#
# -----------------------------------------------------------------------------**
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------------**
# $Log: Makefile,v $
# Revision 1.5 2009/03/23 18:14:06 elphel
# making camvc.html as alias to camvc2.html
#
# Revision 1.4 2008/12/13 23:38:18 elphel
# split camvc2.html, - now only HTML code is in camvc2.html, all the javascript in in camvc_main.js, camvc_video.js and other files that were already separate
#
# Revision 1.3 2008/12/10 22:08:38 elphel
# make now removes temporary file camvc2.ts.html after usage to prevent KDevelop to use it in "find in files"
#
# Revision 1.2 2008/12/05 03:30:26 elphel
# Added camvc_circbuf.js to support circbuf/Exif , restoring functionality available in 7.1
#
# Revision 1.1.1.1 2008/11/27 20:04:03 elphel
#
#
# Revision 1.4 2008/11/17 06:48:04 elphel
# removed camvc2_ccam.js that was already not used
#
# Revision 1.3 2008/11/08 05:54:02 elphel
# snapshot - working on camvc
#
# Revision 1.2 2008/11/02 07:26:14 elphel
# 8.0.alpha11 - started to port ccam.php/camvc2.html
#
# Revision 1.3 2008/04/24 18:51:15 elphel
# added navigation through circbuf
#
# Revision 1.2 2008/04/22 22:21:31 elphel
# Started camvc2 that currently uses most of the same images and javascript files as camvc
#
# Revision 1.1.1.1 2007/09/19 04:51:17 elphel
# This is a fresh tree based on elphel353-2.10
#
# Revision 1.3 2007/09/19 04:51:17 elphel
# Upgraded license (header)
#
#
# Create directories for HTML pages
#
AXIS_USABLE_LIBS = UCLIBC GLIBC
include $(AXIS_TOP_DIR)/tools/build/Rules.axis
# set root as owned and group owner for all files
OWN = -o root -g root
DOCUMENTROOT = $(prefix)/mnt/flash/html
PRODROOT = ../../..
INSTDOCS = 0644
INSTPROG = 0755
#DOCS = camvc.html
DOCS = elphelTabs.js camvcUpgrade.html \
elphelFrames.js elphelContextHelp.js closeme.html camvc_configs.js camvc_dvr.js \
elphelSliders2.js camvc2_i18n.js elphelButtons2.js camvc_camcomm.js camvc_interface.js \
camvc_circbuf.js camvc_video.js camvc_main.js
PHPSCRIPTS= camvc.php
IMGS = images/slider_ball_13x25.png images/slider_ball_13x25_disabled.png images/slider_rail_1x25.png \
images/slider_rail_right13x25.png images/slider_rail_left13x25.png \
images/bg_000000_25.png images/bg_000000_50.png images/bg_000000_75.png \
images/bg_ffffff_25.png images/bg_ffffff_50.png images/bg_ffffff_75.png \
images/bg_dddddd_25.png images/bg_dddddd_50.png images/bg_dddddd_75.png \
images/bg_dddd88_25.png images/bg_dddd88_50.png images/bg_dddd88_75.png \
images/bg_dd88dd_25.png images/bg_dd88dd_50.png images/bg_dd88dd_75.png \
images/bg_88dddd_25.png images/bg_88dddd_50.png images/bg_88dddd_75.png \
images/bg_fffdd0_25.png images/bg_fffdd0_50.png images/bg_fffdd0_75.png \
images/tabs16x24_left_sel.png images/tabs16x24_left_unsel.png \
images/tabs16x24_right_sel.png images/tabs16x24_right_unsel.png \
images/tabs16x24_sel.png images/tabs16x24_sel_unsel.png \
images/tabs16x24_unsel.png images/tabs16x24_unsel_sel.png \
images/tabs16x24_unsel_unsel.png \
images/close_cross_9x9.png images/close_cross_dim_19x19.png \
images/camvc_buttons.png images/empty.png \
images/tooltips65x160.png images/bgmesh8x8.png images/elphel_logo256x256.png \
images/running_25x7.gif images/stopped_25x7.png images/recording_5x5.gif
IMGSRC = images/camvc_buttons.xcf images/tabs16x24.xcf
TIMESTAMP:=$(shell echo $$RANDOM)
install:
############################################################################################################
# Replace links with randomized ones to prevent browser using cache for javascript/image files. #
# If you need to manually update any of *.js *.png files - edit camvc.html, #
# Find .js?<some_ramdom_number> (in the file installed in the camera) #
# or .js?_TIMESTAMP_ if you use original camvc.html file #
# and replace each occurence of "?_TIMESTAMP_" or "?<random_number_you_found>" with "?_something_different"#
# that will prevent camvc.html from using the old, cached values of javascript and image files #
############################################################################################################
# sed -e 's/_TIMESTAMP_/$(TIMESTAMP)/' camvc.html >camvc.ts.html
sed -e 's/_TIMESTAMP_/$(TIMESTAMP)/' camvc2.html >camvc2.ts.html
#prepare some directories anyway
$(INSTALL) $(OWN) -d $(DOCUMENTROOT)/images
#install files
$(INSTALL) $(OWN) -m $(INSTDOCS) $(DOCS) $(DOCUMENTROOT)
$(INSTALL) $(OWN) -m $(INSTDOCS) camvc2.ts.html $(DOCUMENTROOT)/camvc2.html
ln -sf camvc2.html $(DOCUMENTROOT)/index.html
ln -sf camvc2.html $(DOCUMENTROOT)/camvc.html
$(INSTALL) $(OWN) -m $(INSTDOCS) $(IMGS) $(DOCUMENTROOT)/images
$(INSTALL) $(OWN) -m $(INSTDOCS) $(IMGSRC) $(DOCUMENTROOT)/images
$(INSTALL) $(OWN) -m $(INSTDOCS) $(PHPSCRIPTS) $(DOCUMENTROOT)
rm -f camvc2.ts.html
clean:
rm -f *.bak ~*
<?php
/*!*******************************************************************************
*! FILE NAME : camvc.php
*! DESCRIPTION: PHP companion of camvc
*! Copyright (C) 2008 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvc.php,v $
*! Revision 1.9 2010/06/04 01:56:51 elphel
*! Initial support for the multi-sensor operation
*!
*! Revision 1.8 2008/12/10 07:23:45 elphel
*! Added "sleep=" parameter (for simulation of long camera responces)
*!
*! Revision 1.7 2008/12/09 07:51:52 elphel
*! Partial support of ccam.ftp added alerts on non-yet-ported control tabs. Temporary launches autocampars to save selected parameters fro next autostart
*!
*! Revision 1.6 2008/12/05 03:31:31 elphel
*! Multiple changes, some cleanup and working on restoring circbuf/Exif functionality available in 7.1
*!
*! Revision 1.5 2008/12/04 02:24:46 elphel
*! Adding/debugging autoexposure controls
*!
*! Revision 1.4 2008/12/02 00:28:13 elphel
*! multiple bugfixes, making white balance to work and work with camvc
*!
*! Revision 1.3 2008/12/01 07:33:03 elphel
*! Added gains, scales, white balance control
*!
*! Revision 1.2 2008/11/30 05:01:42 elphel
*! new scale for gains
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.6 2008/11/17 23:42:46 elphel
*! changed myval()o accept numbers in ""
*!
*! Revision 1.5 2008/11/16 17:35:53 elphel
*! restored histogram (autoexposure) window control
*!
*! Revision 1.4 2008/11/13 05:40:45 elphel
*! 8.0.alpha16 - modified histogram storage, profiling
*!
*! Revision 1.3 2008/11/10 19:55:51 elphel
*! 8.0.alpha15 - first camvc working with 8.0 (just basic features - no autoexposure, white balance, ...), but it is now really possible (again after it was broken for quite a while) to move sliders and navigator windows without fighting with the camera that tried to move them back
*!
*! Revision 1.2 2008/11/08 23:59:23 elphel
*! snapshot
*!
*! Revision 1.1 2008/11/08 05:54:02 elphel
*! snapshot - working on camvc
*!
*!
*/
function out1x1gif() {
header("Content-Type: image/gif");
header("Content-Length: 35\n");
echo "GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00".
"\xff\xff\xff\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x4c".
"\x01\x00\x3b";
}
function myval ($s) {
$s=trim($s,"\" ");
if (strtoupper(substr($s,0,2))=="0X") return intval(hexdec($s));
else return intval($s);
}
/**
* @brief Decode set=... parameters
* @param $encoded_set - string representation of [frame]/parameter:value array
*/
function decodeSet ($encoded_set) {
global $set,$allNative;
$set=array();
$frame=0;
if (!$encoded_set) return;
$done=explode("/",rtrim($encoded_set,'/'));
foreach ($done as $term) {
$term=explode(":",$term);
if (count($term)==1) {
$frame=$term[0];
} else {
if (($term[1]!="undefined") && ($term[1]!="NaN") && ($term[1]!=666)) { // debug - if the value is set to 666 it will not listen and client should resend it
// $set[$term[0]]= array('value'=>is_array ($term[1])?$term[1]:(is_numeric($term[1])?(float)$term[1]:$term[1]), 'delay'=>$frame, 'native'=>abstractToNative($term[0]));
$set[$term[0]]= array('value'=>$term[1], 'delay'=>$frame, 'native'=>abstractToNative($term[0]));
foreach ($set[$term[0]]['native'] as $nat=>$natVal) $allNative[$nat]=0; /// add to the parameters to be read
}
}
}
}
function fixGammaBlack() {
global $set;
$gampxl=((array_key_exists('gam',$set))?1:0) |
((array_key_exists('pxl',$set))?2:0);
if ($gampxl==0) return;
else if ($gampxl==3) {
$set['pxl']['delay']= $set['gam']['delay']; /// make them have the same delay - just in case
elphel_gamma_add ((int)$set['gam'], (int) $set['pxl']);
} else { /// remove
if ($gampxl & 1) unset ($set['gam']);
if ($gampxl & 2) unset ($set['pxl']);
}
}
///TODO: Don't forget to load gamma tables used - done
function prepSetNative() {
global $set,$allNative,$setNative;
$setNative=array();
foreach ($set as $absPar=>$value) {
$delay= $value['delay'];
$natArr=$value['native']; // array of name/scale pairs
if (!array_key_exists($delay,$setNative)) $setNative[$delay]=array();
switch ($absPar) {
case "comp_run":
$nat=($value['value']=='single')?'COMPRESSOR_SINGLE':'COMPRESSOR_RUN';
$scale=reset ($natArr);
$val=array_search ($value['value'],$scale);
if ($val !== false) $setNative[$delay][$nat]= (int) $val;
break;
case "sens_run":
$nat=($value['value']=='single')?'SENSOR_SINGLE':'SENSOR_RUN';
$scale=reset ($natArr);
$val=array_search ($value['value'],$scale);
if ($val !== false) $setNative[$delay][$nat]= (int) $val;
break;
case "gam":/// return array ("GTAB_R__0816"=>100,"GTAB_G__0816"=>100,"GTAB_GB__0816"=>100,"GTAB_B__0816"=>100);
$k= (float) $value['value'];
$setNative[$delay]["GTAB_R__0816"] =(int) round($natArr["GTAB_R__0816"] * $k);
$setNative[$delay]["GTAB_G__0816"] =(int) round($natArr["GTAB_G__0816"] * $k);
$setNative[$delay]["GTAB_B__0816"] =(int) round($natArr["GTAB_B__0816"] * $k);
$setNative[$delay]["GTAB_GB__0816"]=(int) round($natArr["GTAB_GB__0816"] * $k);
break;
case "pxl":/// return array ("GTAB_R__0824"=>100,"GTAB_G__0824"=>100,"GTAB_GB__0824"=>100,"GTAB_B__0824"=>100);
$k= (float) $value['value'];
$setNative[$delay]["GTAB_R__0824"] =(int) round($natArr["GTAB_R__0824"] * $k);
$setNative[$delay]["GTAB_G__0824"] =(int) round($natArr["GTAB_G__0824"] * $k);
$setNative[$delay]["GTAB_B__0824"] =(int) round($natArr["GTAB_B__0824"] * $k);
$setNative[$delay]["GTAB_GB__0824"]=(int) round($natArr["GTAB_GB__0824"] * $k);
break;
default:
///******************************
$scale=reset ($natArr);
if (is_array($scale)) {
$val=array_search ($value['value'],$scale);
//echo "<pre>scale=";print_r($scale);echo "value="; print_r($value);echo " val=$val \n</pre>";
if ($val !== false) $setNative[$delay][key($natArr)]= (int) $val;
} else $setNative[$delay][key($natArr)]= (int) round(((float) $value['value']) * $scale);
break;
} ///switch ($absPar)
} ///foreach ($set as $absPar=>$value)
/// second pass - copy native values back to the $set array (to be reported to the client to compare to the values read later
foreach ($set as $absPar=>$value) {
$delay= $value['delay'];
$natArr=$value['native']; // array of name/scale pairs
foreach ($natArr as $natName => $natValue) {
$set[$absPar]['native'][$natName]=$setNative[$delay][$natName];
}
} ///foreach ($set as $absPar=>$value)
}
function applySetNative($ahead) {
global $set,$setNative,$pgmFrameNumber;
$pgmFrameNumber=elphel_get_frame()+$ahead;
///NOTE: no verification (and no waiting) that the trget frame is not too far in the future
foreach ($setNative as $since=>$pgmpars) {
elphel_set_P_arr ($pgmpars, $pgmFrameNumber+$since);
}
}
/**
* @brief Scan commands for possible changing gamma tables, calculate them in advance
* (driver can only scale gamma, not calculate prototypes)
* @param todo - array of arrays of parameter chnages
*/
function addGammas() {
global $setNative,$gammas; /// $gammas made global - just for debugging
$gammas=array();
foreach ($setNative as $pars) {
if (array_key_exists('GTAB_R', $pars)) $gammas[$pars['GTAB_R' ]>>16]=1; /// duplicates will be eliminated
if (array_key_exists('GTAB_G', $pars)) $gammas[$pars['GTAB_G' ]>>16]=1;
if (array_key_exists('GTAB_GB',$pars)) $gammas[$pars['GTAB_GB']>>16]=1;
if (array_key_exists('GTAB_B', $pars)) $gammas[$pars['GTAB_B' ]>>16]=1;
if (array_key_exists('GTAB_R__0816', $pars)) $gammas[$pars['GTAB_R__0816'] | ($pars['GTAB_R__0824'] << 8)]=1; /// duplicates will be eliminated
if (array_key_exists('GTAB_G__0816', $pars)) $gammas[$pars['GTAB_G__0816'] | ($pars['GTAB_G__0824'] << 8)]=1; /// duplicates will be eliminated
if (array_key_exists('GTAB_GB__0816', $pars)) $gammas[$pars['GTAB_GB__0816'] | ($pars['GTAB_GB__0824'] << 8)]=1; /// duplicates will be eliminated
if (array_key_exists('GTAB_B__0816', $pars)) $gammas[$pars['GTAB_B__0816'] | ($pars['GTAB_B__0824'] << 8)]=1; /// duplicates will be eliminated
}
// var_dump($gammas);
foreach ($gammas as $gamma_black=>$whatever) {
$black=($gamma_black>>8) & 0xff;
$gamma=($gamma_black & 0xff)*0.01;
elphel_gamma_add ($gamma, $black);
}
}
function abstractToNative($absPar) {
switch ($absPar) {
case "msens": return array ("SENS_AVAIL"=>1);
case "mseq": return array ("MULTI_SEQUENCE"=>1);
case "mmod": return array ("MULTI_MODE"=>1);
case "msel": return array ("MULTI_SELECTED"=>1);
case "e": return array ("EXPOS"=>1000); /// exposure (e) in ms multiplied by 1000.0 to get internal EXPOS in usec
case "ve": return array ("VEXPOS"=>1);
case "fps": return array ("FP1000S"=>1000);
case "fpslm": return array ("FP1000SLIM"=>1000);
case "fpsflags": return array ("FPSFLAGS"=>1);
case "color": return array ("COLOR"=>1);
case "fliph": return array ("FLIPH"=>1);
case "flipv": return array ("FLIPV"=>1);
case "ww": return array ("WOI_WIDTH"=>1);
case "wh": return array ("WOI_HEIGHT"=>1);
case "wl": return array ("WOI_LEFT"=>1);
case "wt": return array ("WOI_TOP"=>1);
case "aw": return array ("ACTUAL_WIDTH"=>1);
case "ah": return array ("ACTUAL_HEIGHT"=>1);
case "dh": return array ("DCM_HOR"=>1);
case "dv": return array ("DCM_VERT"=>1);
case "bh": return array ("BIN_HOR"=>1);
case "bv": return array ("BIN_VERT"=>1);
case "iq": return array ("QUALITY"=>1); // percents
case "gr": return array ("GAINR"=>0x10000);
case "gg": return array ("GAING"=>0x10000);
case "ggb": return array ("GAINGB"=>0x10000);
case "gb": return array ("GAINB"=>0x10000);
// case "rscale":return array ("GTAB_R__1600"=>1024, "GTAB_G__1600"=>1024);
// case "bscale":return array ("GTAB_B__1600"=>1024, "GTAB_G__1600"=>1024);
// case "gscale":return array ("GTAB_GB__1600"=>1024,"GTAB_G__1600"=>1024);
case "rscale":return array ("RSCALE"=>0x10000);
case "bscale":return array ("BSCALE"=>0x10000);
case "gscale":return array ("GSCALE"=>0x10000);
case "wbrs":return array ("WB_SCALE_R" =>0x10000);
case "wbgs":return array ("WB_SCALE_GB"=>0x10000);
case "wbbs":return array ("WB_SCALE_B" =>0x10000);
case "wben":return array ("WB_EN"=>1);
case "bit": return array ("BIT"=>1);
case "gam": return array ("GTAB_R__0816"=>100,"GTAB_G__0816"=>100,"GTAB_GB__0816"=>100,"GTAB_B__0816"=>100);// (0..1.0..)
case "pxl": return array ("GTAB_R__0824"=>1, "GTAB_G__0824"=> 1,"GTAB_GB__0824"=> 1,"GTAB_B__0824"=> 1);
case "csb": return array ("COLOR_SATURATION_BLUE"=>100);
case "csr": return array ("COLOR_SATURATION_RED"=>100);
case "comp_run": return array ("COMPRESSOR_RUN"=>array("stop","single","run"));
case "sens_run": return array ("SENSOR_RUN"=>array("stop","single","run"));
case "sensor": return array ("SENSOR"=>array(4 => "ZR32112", 8 => "ZR32212",32 => "KAC1310",36 => "KAC5000",48 => "MI1300",49 => "MT9M001",50 => "MT9D001",51 => "MT9T001",52 => "MT9P001",64 => "IBIS51300"));
case "decXmask": return array ("SENSOR"=>array(4 => 139, 8 => 139, 32 => 32907, 36 => 15, 48 => 139, 49 => 139, 50 => 139, 51 => 255, 52 => 255, 64 => 0));
case "decYmask": return array ("SENSOR"=>array(4 => 139, 8 => 139, 32 => 32907, 36 => 13, 48 => 139, 49 => 139, 50 => 139, 51 => 255, 52 => 255, 64 => 0));
case "binXmask": return array ("SENSOR"=>array(4 => 0, 8 => 0, 32 => 0, 36 => 3, 48 => 0, 49 => 0, 50 => 0, 51 => 255, 52 => 255, 64 => 0));
case "binYmask": return array ("SENSOR"=>array(4 => 0, 8 => 0, 32 => 0, 36 => 3, 48 => 0, 49 => 0, 50 => 0, 51 => 255, 52 => 255, 64 => 0));
case "hrw": return array ("HISTWND_RWIDTH"=>0x10000);
case "hrh": return array ("HISTWND_RHEIGHT"=>0x10000);
case "hrl": return array ("HISTWND_RLEFT"=>0x10000);
case "hrt": return array ("HISTWND_RTOP"=>0x10000);
case "aef": return array ("AEXP_FRACPIX"=>0x10000);
case "ael": return array ("AEXP_LEVEL"=>0x10000);
case "ae": return array ("AUTOEXP_ON" =>array("off","on"));
case "ftp": return array ("DAEMON_EN_CCAMFTP" =>array("off","on"));
case "aemax": return array ("AUTOEXP_EXP_MAX"=>1000000);
default: return elphel_parse_P_name($absPar)? array ($absPar=>1):array(); // suspecting native constant
}
}
function abstractValue($absPar) {
global $get,$allNative;
switch ($absPar) {
case "gam":/// return array ("GTAB_R__0816"=>100,"GTAB_G__0816"=>100,"GTAB_GB__0816"=>100,"GTAB_B__0816"=>100);
return $allNative["GTAB_G__0816"]/$get[$absPar]["GTAB_G__0816"]; // just from green color
case "pxl":/// return array ("GTAB_R__0824"=>100,"GTAB_G__0824"=>100,"GTAB_GB__0824"=>100,"GTAB_B__0824"=>100);
return $allNative["GTAB_G__0824"]/$get[$absPar]["GTAB_G__0824"]; // just from green color
default:
$value=reset ($get[$absPar]);
if (is_array($value)) return $value[$allNative[key($get[$absPar])]];
else return $value?($allNative[key($get[$absPar])]/$value):'undefined';
}
}
/**
* @brief Decode set=... parameters
* @param $encoded_get - string representation of /parameter/.. array
*/
function decodeGet ($encoded_get) {
global $get,$allNative;
if (!$encoded_get) return array();
$encoded_get=explode("/",trim($encoded_get,'/'));
foreach ($encoded_get as $name) {
$get[$name]=abstractToNative($name);
foreach ($get[$name] as $key=>$value) $allNative[$key]=0;
}
$allNative['FRAME'] = 0; /// always read frame number to reference read parameters to
}
///main()
$MAX_EXECUTION_TIME=20;
$deadline=time()+$MAX_EXECUTION_TIME;
/// set_time_limit(20); - /// does not work!
$exif_get=false;
$circbuf_get=false;
$debug_arr=array();
$toRead=array();
$hist_in_thresh=0.0;
$hist_out_thresh=0.0;
$get=array(); /// abstract parameters to read (i.e. e, ww, fliph)
$set=array(); /// abstract parameters to write (i.e. e, ww, fliph)
$setNative=array(); /// array (indexed by frame Numbers) of array of camera parameters to write (i.e. EXPOS, WOI_WIDTH, FLIPH)
// $getNative=array(); /// array of the native camera parameters to read (i.e. EXPOS, WOI_WIDTH, FLIPH)
$allNative=array(); /// all native parameters that are needed to be read
// $ahead=3;
$ahead=4;
foreach($_GET as $key=>$value) {
switch($key) {
/// _time - will look at FPGA time and program both FPGA and system, _stime - unconditionally program both
case "_time":
$toRead["req_ts"]=$value; /// Request time stamp, as received. Will be used by sender
if (elphel_get_fpga_time() > 100000000) break; // time already set
case "_stime":
$toRead["req_ts"]=$value;
$a=((float) $value)/1000;
elphel_set_fpga_time ($a); // set FPGA time
exec("date -s ".date("mdHiY.s",(int)$a),$out,$ret); // set system time
break;
case "imgsrv":
$toRead["imgsrv"]='http://'.$_SERVER['HTTP_HOST'].':8081/';
break;
case "exif":
$exif_get=$value+0; //page number
break;
case "description":
if ( $value!==null) elphel_set_exif_field(0x10e, $value.chr(0));
break;
case "circbuf":
$circbuf_get=true;
break;
case "hin": // calculate the input and output levels
$hist_in_thresh=$value+0.0;
break;
case "hout": // calculate the input and output levels
$hist_out_thresh=$value+0.0;
break;
case "ahead":
$ahead= myval($value);
break;
case "set":
decodeSet ($value);
break;
case "get":
decodeGet ($value);
break;
case "timeout":
$deadline=time()+$value;
break;
case "sleep":
sleep ($value);
break;
}
}
if (array_key_exists("dbgwait",$_GET)) {
/// NOTE: DOES not notice if connection is reset by the client and keeps php busy !...
while (elphel_get_P_value(ELPHEL_DEBUG+(1<<21)+(28<<16))) {
elphel_skip_frames(1);
if (time()>$deadline) {
error_log("Aborted due to custom timeout");
exit(1);
}
}
}
/// Do whatever needed
$allNative=elphel_get_P_arr($allNative);
$parVal=array();
// foreach ($get as $key=>$value) $parVal[$key]= abstractValue($key);
foreach ($get as $key=>$value) $parVal[$key]= abstractValue($key);
// fixRGBScales();
fixGammaBlack();
prepSetNative();
addGammas();
applySetNative($ahead);
/// TODO:program parameters here, get frame when programmed
/// output result
if ($_GET["out"]=="gif") {
out1x1gif();
exit (0);
}
if ($_GET["debug"]=="1") {
echo "<pre>\n";
echo "\nparVal\n"; print_r($parVal);
echo "\nallNative\n"; print_r($allNative);
echo "\nget\n"; print_r($get);
echo "\nsetNative\n"; print_r($setNative);
echo "\nset\n"; print_r($set);
echo "\ngammas\n"; print_r($gammas);
echo "</pre>\n";
exit (0);
}
$xml = new SimpleXMLElement("<?xml version='1.0'?><pars/>");
if (count($set)>0) {
$xml->addChild ('set');
foreach ($set as $parName=>$parPars) {
$xParName=$xml->set->addChild ($parName);
$xParName->addChild ('frame',$parPars['delay']+$pgmFrameNumber);
$xNative=$xParName->addChild ('native');
foreach ($parPars['native'] as $natName=>$natValue) {
$xNative->addChild ($natName,$natValue);
}
}
}
if (count($parVal)>0) {
$xml->addChild ('frame',$allNative['FRAME']);
$xml->addChild ('get');
foreach ($parVal as $parName=>$parValue) {
$xml->get->addChild ($parName,$parValue);
}
}
if (count($allNative)>0) {
$xml->addChild ('nativeGot');
foreach ($allNative as $natName=>$natValue) {
$xml->nativeGot->addChild ($natName,$natValue);
}
}
// if (count($toRead)>0) $toRead=elphel_get_P_arr($toRead);
if ($_GET["STATE"]!==NULL) $toRead["STATE"]=elphel_get_state();
if ($_GET["imgsrv"]!==NULL) $toRead["imgsrv"]='http://'.$_SERVER['HTTP_HOST'].':8081/';
foreach ($debug_arr as $key=>$value) {
$xml->addChild ($key,$value);
}
$xml->addChild ("ELPHEL_DEBUG__0128",elphel_get_P_value(ELPHEL_DEBUG+(1<<21)+(28<<16)));
foreach ($toRead as $key=>$value) {
$xml->addChild ($key,$value);
}
if ($exif_get!==false) {
$exif_got=elphel_get_exif_elphel($exif_get);
if ($exif_got) {
$xml->addChild ('Exif');
$xml->Exif->addChild ("Exif_page",$exif_get);
foreach ($exif_got as $key=>$value) {
$xml->Exif->addChild ($key,$value);
}
}
}
/// Calculate and output histogram levels if requested (both input and output in the range of 0.0..1.0, inclusive)
/// here $hist_in_thresh corresponds to input signals as fractions of the full scale input data)
if ($hist_in_thresh) {
$xml->addChild ('hist_in');
$xml->hist_in->addChild ('hist_in_thresh',$hist_in_thresh);
$xml->hist_in->addChild ('hist_in_r', elphel_histogram(0,elphel_gamma(0,$hist_in_thresh)));
$xml->hist_in->addChild ('hist_in_g', elphel_histogram(1,elphel_gamma(1,$hist_in_thresh)));
$xml->hist_in->addChild ('hist_in_g2',elphel_histogram(2,elphel_gamma(2,$hist_in_thresh)));
$xml->hist_in->addChild ('hist_in_b', elphel_histogram(3,elphel_gamma(3,$hist_in_thresh)));
}
/// here $hist_out_thresh corresponds to output (8-bit) pixel values as fractions of the 8-bit full scale (255)
if ($hist_out_thresh) {
$xml->addChild ('hist_out');
$xml->hist_out->addChild ('hist_out_thresh',$hist_out_thresh);
$xml->hist_out->addChild ('hist_out_r', elphel_histogram(0,$hist_out_thresh));
$xml->hist_out->addChild ('hist_out_g', elphel_histogram(1,$hist_out_thresh));
$xml->hist_out->addChild ('hist_out_g2',elphel_histogram(2,$hist_out_thresh));
$xml->hist_out->addChild ('hist_out_b', elphel_histogram(3,$hist_out_thresh));
}
///circbuf+exif pointres
if ($circbuf_get) {
$xml->addChild ('circbuf');
$circbuf=elphel_get_circbuf_pointers();
if (is_array ($circbuf)) {
$circbuf_count=count($circbuf);
// $xml->circbuf->addChild ('circbuf_count',$circbuf_count);
for ($i=0;$i<$circbuf_count;$i++) {
$xml->circbuf->addChild ('frame'.$i);
$xml->circbuf->{'frame'.$i}->addChild ('frame' ,$circbuf[$i]['frame']);
$xml->circbuf->{'frame'.$i}->addChild ('circbuf_pointer',$circbuf[$i]['circbuf_pointer']);
$xml->circbuf->{'frame'.$i}->addChild ('exif_pointer' ,$circbuf[$i]['exif_pointer']);
}
}
}
$rslt=$xml->asXML();
header("Content-Type: text/xml");
header("Content-Length: ".strlen($rslt)."\n");
header("Pragma: no-cache\n");
printf($rslt);
?>
<html>
<!--
*! -----------------------------------------------------------------------------**
*! camvc2.html
*!
*! Copyright (C) 2005-2008 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvc2.html,v $
*! Revision 1.21 2011/05/30 00:10:28 elphel
*! Fixed embedding gecko-mediaplayer. Thanks, Kevin!
*!
*! Revision 1.20 2010/08/01 19:30:24 elphel
*! new readonly parameter FRAME_SIZE and it support in the applications
*!
*! Revision 1.19 2010/06/04 01:56:51 elphel
*! Initial support for the multi-sensor operation
*!
*! Revision 1.18 2008/12/13 23:39:50 elphel
*! support for the SnapFull button
*!
*! Revision 1.17 2008/12/11 07:24:35 elphel
*! debug output (commented out anyway)
*!
*! Revision 1.16 2008/12/11 06:37:57 elphel
*! Added animated refresh button
*!
*! Revision 1.15 2008/12/10 22:09:37 elphel
*! Skipping histogram refresh (and hiding it) when compressor is stopped (fro circbuf navigation)
*!
*! Revision 1.14 2008/12/10 18:38:19 elphel
*! Fixed input select element in Konqueror (it would not let to change image resolution)
*!
*! Revision 1.13 2008/12/10 07:24:22 elphel
*! removed unused camera communication states
*!
*! Revision 1.12 2008/12/10 03:07:13 elphel
*! Using non-linear (stretched near high limit) sliders for autoexposure settings
*!
*! Revision 1.11 2008/12/09 23:35:38 elphel
*! Fixed handling Exif image description
*!
*! Revision 1.10 2008/12/09 22:11:56 elphel
*! Fixed resizing, changed color/mono checkbox to mode selector
*!
*! Revision 1.9 2008/12/09 19:25:17 elphel
*! After disabling default actions onmousedown - enabled all input text fields: onmousedown="this.select()" (otherwise they did not get focus when clicking them)
*!
*! Revision 1.8 2008/12/09 16:29:54 elphel
*! Added event.preventDefault() here and there. Really helped - with the current FF buttons were dragged away like images (before I could only fight it using background images, not the regular ones)
*!
*! Revision 1.7 2008/12/09 07:51:52 elphel
*! Partial support of ccam.ftp added alerts on non-yet-ported control tabs. Temporary launches autocampars to save selected parameters fro next autostart
*!
*! Revision 1.6 2008/12/05 08:10:19 elphel
*! Fixed work (at least seems so) circbuf+Exif operation
*!
*! Revision 1.5 2008/12/05 03:31:31 elphel
*! Multiple changes, some cleanup and working on restoring circbuf/Exif functionality available in 7.1
*!
*! Revision 1.4 2008/12/04 02:24:46 elphel
*! Adding/debugging autoexposure controls
*!
*! Revision 1.3 2008/12/02 20:25:46 elphel
*! Reduced range of manual color adjustment in auto white balancing
*!
*! Revision 1.2 2008/12/01 07:33:03 elphel
*! Added gains, scales, white balance control
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.5 2008/11/10 19:55:51 elphel
*! 8.0.alpha15 - first camvc working with 8.0 (just basic features - no autoexposure, white balance, ...), but it is now really possible (again after it was broken for quite a while) to move sliders and navigator windows without fighting with the camera that tried to move them back
*!
*! Revision 1.4 2008/11/08 23:59:23 elphel
*! snapshot
*!
*! Revision 1.3 2008/11/08 05:54:02 elphel
*! snapshot - working on camvc
*!
*! Revision 1.2 2008/11/04 00:15:40 elphel
*! started to work on porting
*!
*! Revision 1.4 2008/05/01 01:32:05 elphel
*! support for the frame number - combining hardware frame counter used by i2c (3-bit) and software one
*!
*! Revision 1.3 2008/04/25 21:32:49 elphel
*! added processing of Exif_Photo_ExposureTime
*!
*! Revision 1.2 2008/04/24 18:51:14 elphel
*! added navigation through circbuf
*!
*! Revision 1.3 2008/02/08 16:33:52 spectr_rain
*! remove FPS doubles
*!
*! Revision 1.2 2007/11/30 19:28:47 spectr_rain
*! added wide resolution 1920x1080 & 1280x720
*!
*! Revision 1.1.1.1 2007/10/02 22:25:10 elphel
*! This is a fresh tree based on elphel353-2.10
*!
*! Revision 1.10 2007/10/02 22:25:10 elphel
*! minor change of the window title
*!
*! Revision 1.9 2007/09/19 17:49:14 elphel
*! Frame rate limit mode is read back from the camera, so several hosts can be nice to each other. But the value fro the fps limit is not read back, just flags
*!
*! Revision 1.8 2007/09/19 04:23:21 elphel
*! fixed layer visibility, restored DVR buttons
*!
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<META http-equiv="PRAGMA" content="NO-CACHE">
<meta http-equiv="Expires" content="0">
<!--<link rel="stylesheet" type="text/css" href="elphel_313_style.css"> -->
<!--.decimation_select {text-align:center;float:left;border:1px solid #ffffff;}
.decimation_block {clear:both;border:1px solid #ff0000;}
.decimation_block1{overflow:auto;border:1px solid #0000ff;}
-->
<!--input {
background-color: #ffffff;
text-align: right;
font-family : sans-serif;
font-size: 8pt;
font-weight: normal;
color: black;
display: inline;
}-->
<style>
body {
font-family : sans-serif;
font-size: 8pt;
font-weight: normal;
color: black;
background-color: white;
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0;
padding: 0;
margin: 0;
}
h1 {
font-family: sans-serif;
font-size: 13pt;
font-weight: normal;
color: black;
}
a {
text-decoration:none;
font-family: sans-serif;
font-weight: bold;
font-size: 8pt;
}
a:link { color: 2f639c }
a:visited { color: 2f639c }
a:active { color: 389165 }
a:hover { color: 389165 }
input {
font-size: 8pt;
display: inline;
}
.decimation_select {text-align:center;float:left;border:0;}
.decimation_block {clear:both;border:0px;}
.decimation_block1{overflow:auto;border:0px}
.settings_item {float:left; width:250px; padding:2px; border-top:0; border-bottom:1px solid #666666; border-left:1px solid #666666; border-right:1px solid #666666;}
.settings_table {position:relative;display:table;width:100%; border-top:0; border-bottom:1px solid #666666; border-left:1px solid #666666; border-right:1px solid #666666;display:table;}
.settings_table_t {position:relative;display:table;width:100%; border-top:1px solid #666666; border-bottom:1px solid #666666; border-left:1px solid #666666; border-right:1px solid #666666;display:table;}
.settings_row {display:table-row; vertical-align: middle;}
.settings_cell{display:table-cell; border-top:0; border-bottom:0; border-left:0; border-right:1px solid #666666; text-align:left; padding: 0px 2px 0px 2px;}
.settings_cell_nrnb{display:table-cell; border-top:0; border-bottom: 1px solid #666666; border-left:0; border-right:1px solid #666666; text-align:left; padding: 2px 2px 2px 2px;}
.settings_cell_rnb{display:table-cell; border-top:0; border-bottom: 1px solid #666666; border-left:0; border-right:0; text-align:left; padding: 2px 2px 2px 2px;}
.settings_cell_nrb{display:table-cell; border-top:0; border-bottom: 0; border-left:0; border-right:1px solid #666666; text-align:left; padding: 2px 2px 2px 2px;}
.settings_cell_rb{display:table-cell; border-top:0; border-bottom: 0; border-left:0; border-right:0; text-align:left; padding: 2px 2px 2px 2px;}
.inline_icon {width:25;height:25;display:inline;}
.float_icon {float:left;}
.separator {position:relative; height:5}
.test_class {border:1px solid black;}
.test_class1 {border:1px solid red;}
.conf_inp {text-align:left; font-weight:bold;}
.conf_inpr {text-align:right;font-weight:bold;}
.input_numeric {text-align:right;}
.input_text {text-align:left;}
.input_readonly_text {text-align:left;background-color:#cccccc;}
.input_readonly_numeric {text-align:right;background-color:#cccccc;}
.input_aexp {text-align:right;color:blue;background-color:#cccc66;}
</style>
<title>Elphel Camera Controls</title>
<script language="javascript" src="elphelSliders2.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="elphelFrames.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="elphelTabs.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="elphelButtons2.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="elphelContextHelp.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="camvc2_i18n.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="camvc_circbuf.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="camvc_camcomm.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="camvc_interface.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="camvc_main.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="camvc_video.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="camvc_configs.js?_TIMESTAMP_" type="text/javascript"></script>
<script language="javascript" src="camvc_dvr.js?_TIMESTAMP_" type="text/javascript"></script>
</head>
<body onload="initOnLoad();" onResize="resizeMainWindow();" onunload="hideStreamPage();" style="background-color: #888888; overflow:hidden;">
<div id="idStartup" style="position:absolute; width:100%; height:100%; background-color: #ffffff; z-index:100; cursor:wait;background-image:url(images/elphel_logo256x256.png?_TIMESTAMP_);background-repeat:no-repeat;background-position:center center;"><H1>Loading...</H1>
</div>
<!-- <div id="DIV_ALL" style="position:absolute; left:0; top:0; width:1024; height:768; background-color: #aa6666; overflow:hidden;">-->
<div id="DIV_ALL" style="position:absolute; left:0; top:0; width:1024; height:768; background-color: #aaaaaa; overflow:hidden;">
<!-- <div id="idVideoViewer_outer" style="display:none;position:absolute;z-index=1;background-color: #aaaaaa;"> Was an error z-index did not work--><!-- z-index >=0 and in new window video is on top -->
<!-- <div id="idVideoViewer_outer" style="display:none;position:absolute;z-index:1;background-color: #aa6666;">--> <!-- z-index >=0 and in new window video is on top -->
<div id="idVideoViewer_outer" style="display:none;position:absolute;z-index:1;background-color: #aa6666;"> <!-- z-index >=0 and in new window video is on top -->
<!-- <div id="idVideoViewer" style="position:relative;z-index:-1;"> -->
<div id="idVideoViewer" style="position:relative;z-index:-1;background-color: #aa6666;">
</div>
<div id="idVideoR" style="display:none; position:fixed; left:260;top:4; font-size:24pt; color:green; z-index:100">R</div>
<div id="idVideoRunButtons" style="position:relative;height:25;background-color:#dddddd">
<div id="idVideoRunButtonsPlayback">
<div id="btnDVRBack_P" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="btnDVRPlay_P" style="position:absolute; left:25; top:0; width:25; height:25;" ></div>
<div id="btnDVRPause_P" style="position:absolute; left:50; top:0; width:25; height:25;" ></div>
<div id="btnDVRStop_P" style="position:absolute; left:75; top:0; width:25; height:25;" ></div>
<div id="btnDVRForward_P" style="position:absolute; left:100;top:0; width:25; height:25;" ></div>
<div id="VideoRun_slIder" style="position:absolute;left:125; top:0; height:25;"></div>
</div>
<div id="idVideoRunButtonsLive">
<div id="btnDVRRecord_L" style="position:absolute; left: 0; top:0; width:25; height:25;" ></div>
<div id="btnDVRStopRecord" style="position:absolute; left:25; top:0; width:25; height:25;" ></div>
</div>
</div>
</div>
<!-- *** Firefox (at least 1.04) does not really shield video plugin even with position:fixed if dimensions are specified in html
javascript - OK *** -->
<!-- seems that background: or background-color in the "idShieldControlsFromPlugin" is needed-->
<div id="idShieldControlsFromPlugin" style="position:fixed;background-color: #888888;z-index:1;"><!-- --></div>
<!-- <iframe id="idShieldControlsFromPlugin" src="javascript:false" style="position: absolute; top: 0px; left: 0px; display: none; width: 1200px; height: 400px; z-index: -100; background-color: #6666aa;" frameborder="0" scrolling="no">aaa</iframe>-->
<!--<div id="idShieldButtonsFromPlugin" style="position:fixed;width:256;">...</div>-->
<div id="idShieldButtonsFromPlugin_0" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_25" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_50" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_75" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_100" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_125" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_150" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_175" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_200" style="position:fixed;"><!-- --></div>
<div id="idShieldButtonsFromPlugin_225" style="position:fixed;"><!-- --></div>
<div id="idDivCameraImage" style="position:absolute;left:256; top:0; width:544; height:256;">
<img id="idCameraImage" src="images/empty.png?_TIMESTAMP_" style="width:100%;height:100%;z-index:-3" onClick="startRefresh()">
<div id="idDivCameraImageCover" style="position:absolute;left:0; top:0; width:100%; height:100%;">
<img src="images/empty.png?_TIMESTAMP_" style="width:1; height:1">
</div>
<div id="idMagnifier_frAmesel" style="position:absolute; left:106; top:0; width:150; height:100;"></div>
</div>
<!-- ============ Menu buttons ======================= -->
<div id="idDivMenu" style="position:absolute; left:0; top:0; width:256; height:25; z-index:100">
<div id="btnCameraShow" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="btnStreamersShow" style="position:absolute; left:25; top:0; width:25; height:25;" ></div>
<div id="btnMonitorShow" style="position:absolute; left:50; top:0; width:25; height:25;" ></div>
<div id="btnDVRShow" style="position:absolute; left:75; top:0; width:25; height:25;" ></div>
<div id="btnNetworkShow" style="position:absolute; left:100; top:0; width:25; height:25;" ></div>
<div id="btnSettingsShow" style="position:absolute; left:125; top:0; width:25; height:25;" ></div>
<!-- <div id="btnInfoShow" style="position:absolute; left:150;top:0; width:25; height:25;" ></div>-->
<div id="btnSnapFull" style="position:absolute; left:150;top:0; width:25; height:25;" ></div>
<div id="btnRefresh" style="position:absolute; left:175;top:0; width:25; height:25;" ></div>
<div id="btnLanguage" style="position:absolute; left:200;top:0; width:25; height:25;" ></div>
<div id="btnHelpShow" style="position:absolute; left:225;top:0; width:25; height:25;" ></div>
</div>
<div id="idDivCameraMenu" style="position:absolute; left:0; top:25; width:256; height:25; z-index:100">
<div id="btnHistShow" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="btnBrConShow" style="position:absolute; left:25; top:0; width:25; height:25;" ></div>
<div id="btnColorShow" style="position:absolute; left:50; top:0; width:25; height:25;" ></div>
<div id="btnPositioningShow" style="position:absolute; left:75; top:0; width:25; height:25;" ></div>
<div id="btnPhotoShow" style="position:absolute; left:100;top:0; width:25; height:25;" ></div>
<div id="btnNetworkShow1" style="position:absolute; left:125;top:0; width:25; height:25;" ></div>
<div id="btnSettingsShow1" style="position:absolute; left:150;top:0; width:25; height:25;" ></div>
</div>
<!-- Info Div -->
<div id="idDivInfo" style="position:absolute; left:0; top:0; width:256;">
<span id="idInfoWidth" style="float:left;font-weight:bold; cursor:pointer;" onclick="released_btnPositioningShow(0);">0</span>
<span style="float:left;" onclick="released_btnPositioningShow(0);">&nbsp;x&nbsp;</span>
<span id="idInfoHeight" style="float:left;font-weight:bold; cursor:pointer;" onclick="released_btnPositioningShow(0);">0</span>
<span id="idInfoAt" style="float:left;"></span>
<span id="idSpanFPS" style="color:green; float:left;font-weight:bold; cursor:pointer;" onclick="released_btnPhotoShow(3);">00.0</span>
<span id="idInfoLabelFPS" style="float:left; cursor:pointer;" onclick="released_btnPhotoShow(3);">fps</span>
<!-- <span id="idInfoLabelRunning" style="float:left;color:green; font-weight:bold; cursor:pointer;" onclick="released_btnPhotoShow(2);">&nbsp;running</span>
<span id="idInfoLabelStopped" style="float:left;color:red; font-weight:bold; cursor:pointer;" onclick="released_btnPhotoShow(2);">&nbsp;stopped</span>-->
<!--
<span id="idInfoLabelRunning" style="float:left;color:green; font-weight:bold; cursor:pointer;" onclick="released_btnPhotoShow(2);"><img
src="images/running_25x7.gif?_TIMESTAMP_" style="width:25;height:7"/></span>
<span id="idInfoLabelStopped" style="float:left;color:red; font-weight:bold; cursor:pointer;" onclick="released_btnPhotoShow(2);"><img
src="images/empty.png?_TIMESTAMP_" style="width:25;height:7"/></span>
-->
<span id="idInfoLabelRunning" style="float:left;color:green; font-weight:bold; cursor:pointer;" onclick="toggleCompressorRun();"><img
src="images/running_25x7.gif?_TIMESTAMP_" style="width:25;height:7"/></span>
<span id="idInfoLabelStopped" style="float:left;color:red; font-weight:bold; cursor:pointer;" onclick="toggleCompressorRun();"><img
src="images/stopped_25x7.png?_TIMESTAMP_" style="width:25;height:7"/></span>
<span style="float:left;">&nbsp;</span>
<span id="idFileSize" style="float:left;">1024K</span>
<!-- <span id="idInfoLabelStrNumber" style="float:left; font-weight:bold; cursor:pointer;" onclick="released_btnPhotoShow(2);">0</span> -->
<div id="idRecStat" style="position:absolute; width:5; height:5; left:240; top:2;cursor:pointer;" onclick="showDVR();"><span
id="idRecOff"><img src="images/empty.png?_TIMESTAMP_" style="width:5;height:5;"/></span><span id="idRecOn" style="display:none;"><img src="images/recording_5x5.gif?_TIMESTAMP_" style="width:5;height:5;" /></span></div>
<!--TODO: Add image file size here too make it work with streamers and static images-->
</div>
<div id="idDivInfoPlus" style="position:absolute; left:0; top:0; width:254;">
<div class="settings_table_t">
<div id="idSensorType_ALL" class="settings_row">
<div id="idSensorType_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div id="idSensorType" class="settings_cell_rnb" >unknown</div>
</div>
<div id="idSensorSize_ALL" class="settings_row">
<div id="idSensorSize_LB" class="settings_cell_nrnb"></div>
<div class="settings_cell_rnb" >
<span id="idSensorWidth"></span>
<span>x</span>
<span id="idSensorHeight"></span>
<span id="idSensorSize_UN"></span>
</div>
</div>
<div id="idActualSize_ALL" class="settings_row">
<div id="idActualSize_LB" class="settings_cell_nrnb"></div>
<div id="idActualSize" class="settings_cell_rnb" >
<a href="images/empty.png?_TIMESTAMP_" id="idImageLink" target="_blank">
<span id="idActualWidth"></span>
<span>x</span>
<span id="idActualHeight"></span>
<span id="idActualSize_UN"></span>
</a>
</div>
</div>
<div id="idAexpInfo_ALL" class="settings_row">
<div id="idAexpInfoPercents" class="settings_cell_nrnb">
<span id="idAexpInfoPercentsValue" style="font-weight:bold; font-style:italic; color:#000000"><b>--</b></span>%<span id="idAexpInfoPercentsUnits">&nbsp;</span>
</div>
<div id="AexpInfoLevels" class="settings_cell_rnb" >
<!-- &nbsp; trying to prevent "jumping" when the text length in state changes (don't want absolute dimensions -->
<span id="idAexpInfoPercentsUnder" >&nbsp;are under&nbsp;</span><span id="idAexpInfoLevelsValue" style="font-weight:bold; font-style:italic; color:#000000"><b>--</b></span>
</div>
</div>
<!-- report here if program is waiting for the camera to respond -->
<div id="idCommStat_ALL" class="settings_row">
<div id="idCommStat_FreeWait" class="settings_cell_nrb">
<span id="idCommStat_Free"><span id="idCommStat_Free_i18n"></span></span>
<span id="idCommStat_Waiting" style="display:none; cursor:pointer;" onclick="ccs_cameraTimeout();"><span id="idCommStat_Waiting_i18n"></span></span>
</div>
<div id="idCommStatRequest" class="settings_cell_rb" >
<span id="idCommStat_None">&nbsp;</span>
<span id="idCommStatRequest_active">
<span id="idCommStat_Command" ><span id="idCommStat_Command_i18n" ></span></span>
<span id="idCommStat_Status" ><span id="idCommStat_Status_i18n" ></span></span>
<!-- <span id="idCommStat_AECommand" ><span id="idCommStat_AECommand_i18n"></span></span>
<span id="idCommStat_AEStatus" ><span id="idCommStat_AEStatus_i18n" ></span></span> -->
<span id="idCommStat_Image" ><span id="idCommStat_Image_i18n"></span></span>
<span id="idCommStat_Histogram" ><span id="idCommStat_Histogram_i18n"></span></span>
<!-- <span id="idCommStat_StrCommand"><span id="idCommStat_StrCommand_i18n"></span></span>
<span id="idCommStat_StrStatus" ><span id="idCommStat_StrStatus_i18n"></span></span>-->
:&nbsp;(<span id="idCommStatTimePassed">0</span>&nbsp;<span id="idCommStatTimePassed_UN"></span>&nbsp;)
</span>
</div>
</div>
</div>
</div>
<!-- end of Info Div -->
<!-- <input type="text" onmousedown="this.select()" id="idDVRStart_TX" size="18" value="2006-03-02 12:00:00" class="input_text"/>-->
<div id="idExifInfo" style="position:absolute; left:0; top:0; width:254;">
<div class="settings_table_t">
<div id="idImageDescription_ALL" class="settings_row">
<div id="idImageDescription_LB" class="settings_cell_nrnb" style="width:30%">Descr:</div>
<div id="idImageDescription" class="settings_cell_rnb" style="font-style:italic;" onClick="ExifModifyDescription();">
</div>
</div>
<div id="idExifFrameNumber_ALL" class="settings_row">
<div id="idExifFrameNumber_LB" class="settings_cell_nrnb">Frame</div>
<div id="idExifFrameNumber" class="settings_cell_rnb" ></div>
</div>
<div id="idExifExposure_ALL" class="settings_row">
<div id="idExifExposure_LB" class="settings_cell_nrnb">Exposure</div>
<div id="idExifExposure" class="settings_cell_rnb" ></div>
</div>
<div id="idTimestamp_ALL" class="settings_row">
<div id="idTimestamp_LB" class="settings_cell_nrnb">Sys. time</div>
<div id="idTimestamp" class="settings_cell_rnb" >XXXX:XX:XX XX:XX:XX.XXXXXX</div>
</div>
<div id="idGPSTime_ALL" class="settings_row">
<div id="idGPSTime_LB" class="settings_cell_nrnb">GPS time</div>
<div id="idGPSTime" class="settings_cell_rnb" >XXXX:XX:XX XX:XX:XX.XXXXXX</div>
</div>
<div id="idGPSLatLong_ALL" class="settings_row">
<div id="idGPSLatLong_LB" class="settings_cell_nrnb">Coord</div>
<div id="idGPSLatLong" class="settings_cell_rnb" >XX.XXXXX, -XXX.XXXXX</div>
</div>
<div id="idGPSAltitudeMode_ALL" class="settings_row">
<div id="idGPSAltitudeMode_LB" class="settings_cell_nrnb">Altitude</div>
<div id="idGPSAltitudeMode" class="settings_cell_rnb" >
<span id="idGPSAltitude"></span>
<span id="idGPSMode_LB"> Mode:</span>
<span id="idGPSMode"></span>
</div>
</div>
<div id="idCompassDirection_ALL" class="settings_row">
<div id="idCompassDirection_LB" class="settings_cell_nrnb">Direction</div>
<div id="idCompassDirection" class="settings_cell_rnb" ></div>
</div>
<div id="idCompassPitchRoll_ALL" class="settings_row">
<div id="idCompassPitchRoll_LB" class="settings_cell_nrb">Pitch/Roll</div>
<div id="idCompassPitchRoll" class="settings_cell_rb" >
<span id="idCompassPitch"></span>
<span>/</span>
<span id="idCompassRoll"></span>
</div>
</div>
</div>
</div>
<!-- end of Exif Info Div -->
<div id="idCircbuf" style="position:absolute; left:0; top:0; width:254;">
<div class="settings_table">
<div class="settings_row" style="vertical-align: middle;">
<div class="settings_cell_rnb">
<div id="btnCircbufPrevFirst" class="float_icon"></div>
</div>
<!-- -->
<div class="settings_cell_rnb">
<input type="text" onmousedown="this.select()" id="idCircbufFrameNo_TX" size="3" value="000" class="input_numeric" style="float:left;" onChange="showCircbufFrame(parseInt(this.value));"/>
</div>
<!-- -->
<div class="settings_cell_rnb">
<div id="idCircbufSeparator" style="float:left;">:</div>
</div>
<!--
<div class="settings_cell_rnb">
<div id="idCircbufNumber" style="float:left;">123</div>
</div>
-->
<div class="settings_cell_rnb">
<input type="text" onmousedown="this.select()" id="idCircbufNumber_TX" size="3" value="000" class="input_readonly_numeric" style="float:left;"/>
</div>
<div class="settings_cell_rnb">
<div id="btnCircbufNextLast" class="float_icon"></div>
<div id="btnCircbufRun" class="float_icon"></div>
<div id="btnCircbufSingle" class="float_icon"></div>
</div>
</div>
</div>
</div>
<div id="idDVRInfo" style="position:absolute; left:0; top:0; width:254;">
<div class="settings_table_t">
<div id="idDVRLinkAll" class="settings_row">
<div id="idDVRLink_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div class="settings_cell_rnb" >
<a href="images/empty.png?_TIMESTAMP_" id="idDVRLink_LN" target="_blank"><span id="idDVRFileShortName">---</span></a>
</div>
</div>
<div id="idDVRFileFormatAll" class="settings_row">
<div id="idDVRFileFormat_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div id="idDVRFileFormat" class="settings_cell_rnb" >---</div>
</div>
<div id="idDVRFileSizeAll" class="settings_row">
<div id="idDVRFileSize_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div class="settings_cell_rnb" ><span id="idDVRFileSize">---</span><span id="idDVRFileSize_UN">-</span></div>
</div>
<div id="idDVRFrameSizeAll" class="settings_row">
<div id="idDVRFrameSize_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div class="settings_cell_rnb" ><span id="idDVRFrameWidth">---</span>x<span id="idDVRFrameHeight">---</span></div>
</div>
<div id="idDVRFPSAll" class="settings_row">
<div id="idDVRFPS_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div class="settings_cell_rnb" ><span id="idDVRFPS">---</span>&nbsp;<span id="idDVRFPS_UN">---</span></div>
</div>
<div id="idDVRFileStartAll" class="settings_row">
<div id="idDVRFileStart_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div id="idDVRFileStart" class="settings_cell_rnb" >---</div>
</div>
<div id="idDVRFileEndAll" class="settings_row">
<div id="idDVRFileEnd_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div id="idDVRFileEnd" class="settings_cell_rnb" >---</div>
</div>
<div id="idDVRFileDurationAll" class="settings_row">
<div id="idDVRFileDuration_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div id="idDVRFileDuration" class="settings_cell_rnb" >---</div>
</div>
<div id="idDVRFileFramesAll" class="settings_row">
<div id="idDVRFileFrames_LB" class="settings_cell_nrnb" style="width:40%"></div>
<div id="idDVRFileFrames" class="settings_cell_rnb" >---</div>
</div>
<div id="idDVRFilePositionAll" class="settings_row">
<div id="idDVRFilePosition_LB" class="settings_cell_nrb" style="width:40%"></div>
<div id="idDVRFilePosition" class="settings_cell_rb" >---</div>
</div>
<div id="idDVRRecordingSinceAll" class="settings_row">
<div id="idDVRRecordingSince_LB" class="settings_cell_nrb" style="width:40%"></div>
<div id="idDVRRecordingSince" class="settings_cell_rb" >---</div>
</div>
</div>
</div>
<!-- DVR buttons -->
<div id="idDVRButtons" style="position:absolute; left:0; top:50; width:256; height:25">
<div id="btnDVRBack" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="btnDVRPlay" style="position:absolute; left:25; top:0; width:25; height:25;" ></div>
<div id="btnDVRPause" style="position:absolute; left:50; top:0; width:25; height:25;" ></div>
<div id="btnDVRStop" style="position:absolute; left:75; top:0; width:25; height:25;" ></div>
<div id="btnDVRForward" style="position:absolute; left:100;top:0; width:25; height:25;" ></div>
<div id="btnDVRRecord" style="position:absolute; left:200;top:0; width:25; height:25;" ></div>
<div id="btnDVRSettings" style="position:absolute; left:225;top:0; width:25; height:25;" ></div>
</div>
<div id="idDVRSlider" style="position:absolute; left:0; top:0; width:253; height:25; ">
<div id="btnDVRList" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="idDVRSlider_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
<div id="idDivDVR" style="position:absolute; left:0; top:25; width:256;">
<div id="idDVRStartAll" class="settings_item">
<span id="idDVRStart_LB" style="float:left;"></span>
<div id= "idDVRSearch_BN" style="float:right; width:25;height:25;"></div>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idDVRStart_TX" size="18" value="2006-03-02 12:00:00" class="input_text"/>
</span>
</div>
</div>
<div id="idDivHist" style="position:absolute; left:0; top:25; width:256;">
<img id="imgHistogram" width="256" height="128" border ="0" src="pnghist.cgi?height=128&sqrt=1&scale=3&average=10&fillz=1&linterpz=1&colors=41" onClick="toggleHistControls();">
</div>
<!-- positioning -->
<!--http://www.jakpsatweb.cz/css/css-vertical-center-solution.html Use it to fix for IE later-->
<div id="idWindow" style="position:absolute; left:0; top:25; width:256;">
<div id="idWindow_frAmesel" style="position:absolute; left:94; top:0; width:162; height:125; background-image:url(images/bgmesh8x8.png?_TIMESTAMP_);">
</div>
<div id="idWindow_frAmeselT_WH" class="settings_table" style="width:94;">
<div class="settings_row">
<div id="idWindow_frAmeselT_Width" class="settings_cell_rnb">
<div id="idWindow_frAmeselT_Width_BTN" class="float_icon"></div>
<input type="text" onmousedown="this.select()" id="idWindow_frAmeselT_TXWidth" size="5" value="2048" onchange="frAmeselOnTextChange(this.id,'w');" class="input_numeric" onfocus="this.myfocus=true;" onblur="this.myfocus=false;"/>
<span id="idWindow_frAmeselT_Width_pxpc" onmouseover="pix2perc1('h');" onmouseout="pix2perc1('o');" onmousedown="pix2perc1('d');" onmouseup="pix2perc1('u');">%</span>
</div>
</div>
<div class="settings_row">
<div id="idWindow_frAmeselT_Height" class="settings_cell_rnb">
<div id="idWindow_frAmeselT_Height_BTN" class="float_icon"></div>
<input type="text" onmousedown="this.select()" id="idWindow_frAmeselT_TXHeight" size="5" value="1536" onChange="frAmeselOnTextChange(this.id,'h');" class="input_numeric" onfocus="this.myfocus=true;" onblur="this.myfocus=false;"/>
<span id="idWindow_frAmeselT_Height_pxpc" onmouseover="pix2perc1('h');" onmouseout="pix2perc1('o');" onmousedown="pix2perc1('d');" onmouseup="pix2perc1('u');" style="cursor:pointer;">%</span>
</div>
</div>
<div class="settings_row">
<div id="idWindow_frAmeselT_Left" class="settings_cell_rnb">
<div id="idWindow_frAmeselT_Left_BTN" class="float_icon"></div>
<input type="text" onmousedown="this.select()" id="idWindow_frAmeselT_TXLeft" size="5" value="0" onChange="frAmeselOnTextChange(this.id,'l');" class="input_numeric" onfocus="this.myfocus=true;" onblur="this.myfocus=false;"/>
<span id="idWindow_frAmeselT_Left_pxpc" onmouseover="pix2perc1('h');" onmouseout="pix2perc1('o');" onmousedown="pix2perc1('d');" onmouseup="pix2perc1('u');" style="cursor:pointer;">%</span>
</div>
</div>
<div class="settings_row">
<div id="idWindow_frAmeselT_Top" class="settings_cell_rb">
<div id="idWindow_frAmeselT_Top_BTN" class="float_icon"></div>
<input type="text" onmousedown="this.select()" id="idWindow_frAmeselT_TXTop" size="5" value="0" onChange="frAmeselOnTextChange(this.id,'t');" class="input_numeric" onfocus="this.myfocus=true;" onblur="this.myfocus=false;"/>
<span id="idWindow_frAmeselT_Top_pxpc" onmouseover="pix2perc1('h');" onmouseout="pix2perc1('o');" onmousedown="pix2perc1('d');" onmouseup="pix2perc1('u');" style="cursor:pointer;">%</span>
</div>
</div>
</div>
<!-- class="input_numeric"/ -->
<div id="idAexp_frAmeselT_WH" class="settings_table" style="width:94;">
<div class="settings_row">
<div id="idAexp_frAmeselT_Width" class="settings_cell_rnb">
<div id="idAexp_frAmeselT_Width_BTN" class="float_icon"></div>
<input type="text" onmousedown="this.select()" id="idAexp_frAmeselT_TXWidth" size="5" value="2048" onchange="frAmeselOnTextChange(this.id,'w');" class="input_aexp" onfocus="this.myfocus=true;" onblur="this.myfocus=false;"/>
<span id="idAexp_frAmeselT_Width_pxpc" onmouseover="pix2perc1('h');" onmouseout="pix2perc1('o');" onmousedown="pix2perc1('d');" onmouseup="pix2perc1('u');" style="cursor:pointer;">%</span>
</div>
</div>
<div class="settings_row">
<div id="idAexp_frAmeselT_Height" class="settings_cell_rnb" >
<div id="idAexp_frAmeselT_Height_BTN" class="float_icon"></div>
<input type="text" onmousedown="this.select()" id="idAexp_frAmeselT_TXHeight" size="5" value="1536" onChange="frAmeselOnTextChange(this.id,'h');" class="input_aexp" onfocus="this.myfocus=true;" onblur="this.myfocus=false;"/>
<span id="idAexp_frAmeselT_Height_pxpc" onmouseover="pix2perc1('h');" onmouseout="pix2perc1('o');" onmousedown="pix2perc1('d');" onmouseup="pix2perc1('u');" style="cursor:pointer;">%</span>
</div>
</div>
<div class="settings_row">
<div id="idAexp_frAmeselT_Left" class="settings_cell_rnb">
<div id="idAexp_frAmeselT_Left_BTN" class="float_icon"></div>
<input type="text" onmousedown="this.select()" id="idAexp_frAmeselT_TXLeft" size="5" value="0" onChange="frAmeselOnTextChange(this.id,'l');" class="input_aexp" onfocus="this.myfocus=true;" onblur="this.myfocus=false;"/>
<span id="idAexp_frAmeselT_Left_pxpc" onmouseover="pix2perc1('h');" onmouseout="pix2perc1('o');" onmousedown="pix2perc1('d');" onmouseup="pix2perc1('u');" style="cursor:pointer;">%</span>
</div>
</div>
<div class="settings_row">
<div id="idAexp_frAmeselT_Top" class="settings_cell_rb">
<div id="idAexp_frAmeselT_Top_BTN" class="float_icon"></div>
<input type="text" onmousedown="this.select()" id="idAexp_frAmeselT_TXTop" size="5" value="0" onChange="frAmeselOnTextChange(this.id,'t');" class="input_aexp" onfocus="this.myfocus=true;" onblur="this.myfocus=false;"/>
<span id="idAexp_frAmeselT_Top_pxpc" onmouseover="pix2perc1('h');" onmouseout="pix2perc1('o');" onmousedown="pix2perc1('d');" onmouseup="pix2perc1('u');" style="cursor:pointer;">%</span>
</div>
</div>
</div>
<div class="settings_table" style="width:100%;">
<div id="idWindow_frAmeselT_U" class="settings_row">
<div id="ImageResolution" class="settings_cell_rb">
<select name="ImageSize" id="idImageSize" onchange="updateFromSizeSelector(this.id);">
<option id="ImageSizeCustom" value="custom">custom</option>
<option id="ImageSizeFull" value="full window">full window</option>
<option value="2592x1936">2592x1936</option>
<option value="2048x1536">2048x1536</option>
<option value="1920x1088">1920x1088</option>
<option value="1600x1200">1600x1200</option>
<option value="1280x1024">1280x1024</option>
<option value="1280x720">1280x720</option>
<option value="1024x768">1024x768</option>
<option value="800x600">800x600</option>
<option value="640x480">640x480</option>
<option value="320x240">320x240</option>
</select>
<span id="idWindow_frAmeselT_moreLess" onmouseover="moreLess(this.id,'h');" onmouseout="moreLess(this.id,'o');" onmousedown="moreLess(this.id,'d');" onmouseup="moreLess(this.id,'u');" style="cursor:pointer;">
<span id="idWindow_frAmeselT_more" style="cursor:pointer;"></span>
<span id="idWindow_frAmeselT_less" style="cursor:pointer;"></span>
</span>
</div>
</div>
<div id="idAexp_frAmeselT_U" class="settings_row">
<div id="idAexp_frAmeselT_Units" class="settings_cell_nrb" style="height:25;">
<span id="idAexp_frAmeselT_moreLess" onmouseover="moreLess(this.id,'h');" onmouseout="moreLess(this.id,'o');" onmousedown="moreLess(this.id,'d');" onmouseup="moreLess(this.id,'u');" style="cursor:pointer;">
<span id="idAexp_frAmeselT_more" style="cursor:pointer;"></span>
<span id="idAexp_frAmeselT_less" style="cursor:pointer;"></span>
</span>
</div>
</div>
</div>
</div>
<!--
-->
<!-- end of positioning -->
<!-- histogram controls -->
<!-- <div id="idDivHistControl" style="display:none; position:absolute; left:0; top:281; width:256; "><form>
</div>-->
<!-- end of Histogram Controls -->
<!-- Video Control -->
<div id="idDivVideo" style="display:none; position:absolute; left:0; top:0; width:256;">
<div id="idVideoRunAll" class="settings_item">
<span id="idVideoRun_LB" style="float:left;"></span>
<div id="idVideoRun_CB" style=" width:25; height:25;float:right;" ></div>
</div>
<!--
<div id="idVideoViewAll" class="settings_item">
<span id="idVideoView_LB" style="float:left;"></span>
<div id="idVideoView_CB" style=" width:25; height:25;float:right;" ></div>
</div>
-->
<div id="idVideoLimitFPSAll" class="settings_item">
<span id="idVideoLimitFPS_LB" style="float:left;"></span>
<div id="idVideoLimitFPS_CB" style=" width:25; height:25;float:right;" ></div>
</div>
<div id="idVideoFPSLimitAll" class="settings_item">
<span id="idVideoFPSLimit_LB" style="float:left;"></span>
<span style="float:right">
<input id="idVideoFPSLimit_TX" type="text" size="5" maxlength="5" value="30" onChange="updateFPSLimit();" class="input_numeric"/>
<span id="idVideoFPSLimit_UN">fps</span>
</span>
</div>
<div id="idVideoMaintainFPSAll" class="settings_item">
<span id="idVideoMaintainFPS_LB" style="float:left;"></span>
<div id="idVideoMaintainFPS_CB" style=" width:25; height:25;float:right;" ></div>
</div>
<span id="idDivVideo_moreLess" onmouseover="moreLess(this.id,'h');" onmouseout="moreLess(this.id,'o');" onmousedown="moreLess(this.id,'d');" onmouseup="moreLess(this.id,'u');" style="cursor:pointer;">
<span id="idDivVideo_more"></span>
<span id="idDivVideo_less"></span>
</span>
</div>
<!--
<div id="idDivVideoControl" style="display:none; position:absolute; left:0; top:0; width:256; height:100;">
Nothing here yet - will be streamer control
</div>
-->
<div id="idDivWebcamControl" style="position:absolute; left:0; top:0; width:256; height:200; ">
<div id="idNetworkTabs" style="position:absolute; left:0; top:0; width:256; height:24; "></div>
<div id="idNetworkTabs_div1" style="position:absolute; left:0; top:24; width:256;">
<!-- <input id="idNetworkTabs_div1_autofill" type="hidden" value="autofillWebCam();"/> -->
<div id="idNetworkTabs_div1_head" class="settings_item">
<div id="idNetworkTabs_div1_LB" style="float:left;">Network Settings</div>
</div>
</div>
<div id="idNetworkTabs_div2" style="position:absolute; left:0; top:24; width:256;">
<div id="idNetworkTabs_div2_head" class="settings_item">
<div id="idNetworkTabs_div2_LB" style="float:left;">Remote FTP Server</div>
</div>
</div>
<div id="idNetworkTabs_div3" style="position:absolute; left:0; top:24; width:256;">
<input id="idNetworkTabs_div3_autofill" type="hidden" value="autofillWebCam();"/>
<div id="idNetworkTabs_div3_head" class="settings_item">
<div id="idNetworkTabs_div3_LB" style="float:left;">Webcam Settings</div>
</div>
</div>
<div id="idNetworkTabs_div4" style="position:absolute; left:0; top:24; width:256;">
<input id="idNetworkTabs_div4_autofill" type="hidden" value="autofillWebCamAexp();"/>
<div id="idNetworkTabs_div4_head" class="settings_item">
<div id="idNetworkTabs_div4_LB" style="float:left;">Webcam Autoexposure</div>
</div>
</div>
</div>
<!-- end of Webcam Control -->
<!-- Help -->
<!-- <div id="idDivHelp" style="display:none; position:absolute; left:0; top:0; width:256; height:100; background-color: #ddddbb; font-size:14px;">-->
<div id="idDivHelp" style="display:none; position:absolute; left:0; top:0; width:256;">
<span id="idHelp">
No help yet
</span>
</div>
<!-- end of Help -->
<!-- Help-license -->
<!-- <div id="idDivLicense" style="display:none; position:absolute; left:0; top:0; width:256; height:410; background-color: #ddddbb; font-size:14px;">-->
<div id="idDivLicense" style="display:none; position:absolute; left:0; top:0; width:256;" onresize="showWindow();">
<span id="idDivLicense_TX"></span>
</div>
<!-- end of Help-license -->
<!-- Geometry Controls -->
<div id="idDivGeometry" style="display:none; position:absolute; left:0; top:0; width:256; background-color: #bbdddd; font-size:14px;"><form>
nothing here now
</div>
<!-- end of Geometry Controls -->
<!-- Exposure+gamma -->
<div id="idDivExposGamma" style="position:absolute; left:0; top:281; width:256; height:75; background-color: #ff00ff">
<div id="exposure" style="position:absolute; left:0; top:0; width:254; height:25;">
<div id="exposure_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="exposure_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
<div id="gamma" style="position:absolute; left:0; top:25; width:254; height:25;">
<div id="gamma_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="gamma_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
<div id="blackLev" style="position:absolute; left:0; top:50; width:254; height:25;">
<div id="blackLev_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="blackLev_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
</div>
<!-- end of Exposure+gamma -->
<!--/*
{id:"idDivColors", opt:"C", bg:"ffffff", dspl:1,hoverSize: 19,crossSize:9,hoverURL:"images/close_cross_dim_19x19.png?_TIMESTAMP_",crossURL:"images/close_cross_9x9.png?_TIMESTAMP_",callback:"showWindow();"},
{id:"idDivWB", opt:"C", bg:"ffffff", dspl:1,hoverSize: 19,crossSize:9,hoverURL:"images/close_cross_dim_19x19.png?_TIMESTAMP_",crossURL:"images/close_cross_9x9.png?_TIMESTAMP_",callback:"showWindow();"},
{id:"idDivGains", opt:"C", bg:"ffffff", dspl:1,hoverSize:
*/-->
<!-- Colors -->
<div id="idDivColors" style="position:absolute; left:0; top:341; width:256; height:25; background-color: #00ffff">
<div id="gainGreen" style="position:absolute; left:0; top:0; width:254; height:25;">
<div id="gainGreen_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="gainGreen_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
</div>
<!-- end of Colors -->
<!-- White balance correction -->
<div id="idDivWB" style="position:absolute; left:0; top:341; width:256; height:50; background-color: #00ffff">
<div id="autoRed2Green" style="position:absolute; left:0; top:0; width:254; height:25;">
<div id="autoRed2Green_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="autoRed2Green_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
<div id="autoBlue2Green" style="position:absolute; left:0; top:25; width:254; height:25;">
<div id="autoBlue2Green_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="autoBlue2Green_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
</div>
<!-- end of White balance correction -->
<!-- Gains/Scales -->
<div id="idDivGains" style="position:absolute; left:0; top:341; width:256; height:50; background-color: #00ffff">
<div id="gainRed" style="position:absolute; left:0; top:0; width:254; height:25;display:none;">
<div id="gainRed_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="gainRed_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
<div id="gainRed2Green" style="position:absolute; left:0; top: 0; width:254; height:25;">
<div id="gainRed2Green_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="gainRed2Green_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
<div id="gainBlue" style="position:absolute; left:0; top:25; width:254; height:25;display:none;">
<div id="gainBlue_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="gainBlue_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
<div id="gainBlue2Green" style="position:absolute; left:0; top:25; width:254; height:25;">
<div id="gainBlue2Green_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="gainBlue2Green_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
</div>
<!-- end of Gains/Scales -->
<!-- ColorSat -->
<div id="idDivColorSat" style="position:absolute; left:0; top:341; width:256; height:50; background-color: #00ffff">
<div id="colorSat" style="position:absolute; left:0; top:0; width:254; height:25;">
<div id="colorSat_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="colorSat_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
<div id="colorDiffSat" style="position:absolute; left:0; top:25; width:254; height:25;">
<div id="colorDiffSat_button" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>
<div id="colorDiffSat_slIder" style="position:absolute; left:25; top:0; width:229; height:25;"></div>
</div>
</div>
<!-- end of ColorSat -->
<!-- white balance -->
<div id="idWhiteBalance" style="display:none; position:absolute; left:0; top:341; width:256; height:100;">
<!-- -->
</div>
<!-- end of white balance -->
<!-- <div id="idDivSettings" style="display:none; position:absolute; left:0; top:0; width:256; height:200; "> -->
<div id="idDivSettings" style="position:absolute; left:0; top:0; width:256; height:200; ">
<div id="idSettingsTabs" style="position:absolute; left:0; top:0; width:256; height:24; "></div>
<div id="idSettingsTabs_div1" style="position:absolute; left:0; top:24; width:256;">
<div id="idDVRServerAll" class="settings_item">
<span id="idDVRServer_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idDVRServer_TX" size="15" value="" class="input_text" onchange="dvrServerIpChanged();"/>:<input
type="text" id="idDVRServerPort_TX" size="5" value="" class="input_text" onchange="dvrServerIpChanged();"/> <!-- 8025 -->
</span>
</div>
<div id="idDVRCameraIDAll" class="settings_item">
<span id="idDVRCameraID_LB" style="float:left;"></span>
<span style="float:right;">
<input readonly type="text" id="idDVRCameraID_TX" size="15" value="" class="input_readonly_text"/>
</span>
</div>
<div id="idDVRCameraIP1All" class="settings_item">
<span id="idDVRCameraIP1_LB" style="float:left;"></span>
<span style="float:right;">
<!-- <input disabled type="text" id="idDVRCameraIP1_TX" size="15" value="" class="input_text"/>:<input
disabled type="label" id="idDVRCameraIP1Port_TX" size="5" value="" class="input_text"/> -->
<input readonly type="text" id="idDVRCameraIP1_TX" size="15" value="" class="input_readonly_text"/>
</span>
</div>
<div id="idDVRCameraIP2All" class="settings_item">
<span id="idDVRCameraIP2_LB" style="float:left;"></span>
<span style="float:right;">
<input readonly type="text" id="idDVRCameraIP2_TX" size="15" value="" class="input_readonly_text"/>:<input
readonly type="text" id="idDVRCameraIP2Port_TX" size="5" value="" class="input_readonly_text"/>
</span>
</div>
<div id="idDVRMaxFileSizeAll" class="settings_item">
<span id="idDVRMaxFileSize_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idDVRMaxFileSize_TX" size="4" value="" class="input_numeric"/>&nbsp;<span id="idDVRMaxFileSize_UN"></span>
</span>
</div>
<div id="idDVRMaxFileDurationAll" class="settings_item" style="display:none;">
<span id="idDVRMaxFileDuration_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idDVRMaxFileDuration_TX" size="4" value="" class="input_numeric"/>&nbsp;<span id="idDVRMaxFileDuration_UN"></span>
</span>
</div>
<div id="idDVRLocationAll" class="settings_item">
<span id="idDVRLocation_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idDVRLocation_TX" size="20" value="" class="input_text"/>
</span>
</div>
<div id="idDVRRegisterAll" class="settings_item">
<span id="idDVRRegister_LB" style="float:left;"></span>
<div id= "idDVRRegister_BN" style="float:right; width:25;height:25;"></div>
</div>
<div id="idDVRLoopAll" class="settings_item">
<span id="idDVRLoop_LB" style="float:left;"></span>
<div id= "idDVRLoop_CB" style="float:right; width:25;height:25;"></div>
</div>
<div id="idDVRNextPlayAll" class="settings_item">
<span id="idDVRNextPlay_LB" style="float:left;"></span>
<div id= "idDVRNextPlay_CB" style="float:right; width:25;height:25;"></div>
</div>
<div id="idDVRSoftwareAll" class="settings_item">
<span id="idDVRSoftware_LB" style="float:left;"></span>&nbsp;<a href="#" id= "idDVRSoftware" target="_blank">DVR software</a>
</div>
<div id="idDVRSliderDelayAll" class="settings_item">
<span id="idDVRSliderDelay_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idDVRSliderDelay_TX" size="4" value="500" class="input_numeric"/><span id="idDVRSliderDelay_UN"></span>
</span>
</div>
<!-- <div id="btnHistShow" style="position:absolute; left:0; top:0; width:25; height:25;" ></div>-->
<!-- <span>This is Tab1 </span>-->
</div>
<div id="idSettingsTabs_div2" style="position:absolute; left:0; top:24; width:256;">
<div id="idTranslucencyAll" class="settings_item">
<span id="idTranslucency" style="float:left;">Translucency</span>
<div id="btnTransl100" style="float:right; width:25; height:25;" ></div>
<div id="btnTransl75" style="float:right; width:25; height:25;" ></div>
<div id="btnTransl50" style="float:right; width:25; height:25;" ></div>
<div id="btnTransl25" style="float:right; width:25; height:25;" ></div>
<div id="btnTransl0" style="float:right; width:25; height:25;" ></div>
<div id="btnTranslNo" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idDisplayTypeAll" class="settings_item">
<span id="idDisplayType_LB" style="float:left;">Translucency</span>
<div id="btnDisplayVideo" style="float:right; width:25; height:25;" ></div>
<div id="btnDisplayStill" style="float:right; width:25; height:25;" ></div>
<div id="btnDisplayNone" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idFPSReduceAll" class="settings_item">
<span id="idFPSReduce_LB" style="float:left;"></span>
<span style="float:right;">1/<input type="text" onmousedown="this.select()" id="idFPSReduce_TX" size="1" value="1" class="input_numeric" onchange="fpsReduceChanged();"/></span>
</div>
<div id="idEnableImageRefresh" class="settings_item">
<div id="idEnableImageRefresh_SP" style="float:left;">
<span id="idEnableImageRefresh_LB" style="float:left;"></span>
<div id="idEnableImageRefresh_CB" style="float:left; width:25; height:25;" ></div>
</div>
<div id="idEnableImageRefreshFor_SP" style="float:left;">
<span id="idEnableImageRefreshFor_LB" style="float:left;"></span>
<input type="text" onmousedown="this.select()" id="idEnableImageRefreshFor_TX" size="3" value="10" class="input_numeric" style="float:left;"
onchange="gRequests.refreshDuration=Math.round(parseFloat(document.getElementById(this.id).value)*1000);startRefresh();"/>
<span id="idEnableImageRefreshSec_LB" style="float:left;"></span>
</div>
</div>
<div id="idMagnifier" class="settings_item" style="position:relative; height:25;">
<div id="btnMagnifierNo" style="position:absolute; left:0;top:0; width:25; height:25;" ></div>
<div id="btnMagnifierFrameless" style="position:absolute; left:25;top:0; width:25; height:25;" ></div>
<div id="btnMagnifierFramed" style="position:absolute; left:50;top:0; width:25; height:25;" ></div>
<div id="MagnifierZoom_slIder" style="position:absolute; left:75;top:0; width:175; height:25;" ></div>
</div>
</div>
<div id="idSettingsTabs_div3" style="position:absolute; left:0; top:24; width:256;">
<div id="idSettingsTabs_div3_head" class="settings_item">
<div id="idSettingsTabs_div3_LB" style="float:left;">Network Settings</div>
</div>
</div>
<div id="idSettingsTabs_div4" style="position:absolute; left:0; top:24; width:256;">
<div class="settings_table">
<div class="settings_row">
<div id="idAexp_LBALL" class="settings_cell_rnb">
<div id="idAexpOn_CB" style="float:left; width:25; height:25;"></div>
<div id="idAexp_LB"></div>
</div>
</div>
<div class="settings_row">
<div id="idAexpLevels" class="settings_cell_rnb" style="position:relative; width:256;height:25;">
<div id="idAexpLevels_LBTN" style="float:left; width:25; height:25;"></div>
<div id="idAexpLevels_slIder" style="position:absolute; left:30; width:225;height:25;"></div>
</div>
</div>
<div class="settings_row">
<div id="idAexpPercents" class="settings_cell_rnb" style="position:relative; width:256;height:25;">
<div id="idAexpPercents_LBTN" style="float:left; width:25; height:25;"></div>
<div id="idAexpPercents_slIder" style="position:absolute; left:30; width:225;height:25;"></div>
</div>
</div>
<div class="settings_row">
<div id="idAexpMonitor" class="settings_cell_rb" style="position:relative; width:256;height:25;">
<div id="idAexpMonitor_LBTN" style="float:left; width:25; height:25;"></div>
<div id="idAexpMonitor_slIder" style="position:absolute; left:30; width:225;height:25;"></div>
</div>
</div>
</div><!-- table -->
<div id="idMaxAndOverExpos" class="settings_table" style="width:256">
<div id="idAexpMaxExpos" class="settings_row">
<div class="settings_cell_rnb">
<span id="idAexpMaxExpos_LB" style="float:left;">Maximal exposure</span>
<span id="idAexpMaxExpos_TXUN" style="white-space: nowrap; float:right">
<input id="idAEMax" type="text" size="8" maxlength="8" value="1000" onChange="setAEMax();" class="input_numeric"/>
<span id="idAEMax_UN">ms</span>
</span>
</div>
</div>
<div id="idAexpOverExp" class="settings_row" style="display:none" > <!-- will be removed later as it is not used anymore -->
<div class="settings_cell_rnb">
<span id="idAexpOverExp_LB" >Maximal overexposed pixels</span>
<!-- <span id="idAexpMaxExpos_TXUN" style="white-space: nowrap; float:right">-->
<div id="idAexpMaxExpos_TXUN" style="float:right">
<!-- <span id="idAexpMaxExpos_TXUN" style="white-space: nowrap; float:right">-->
<input id="idAEOExp" type="text" size="8" maxlength="8" value="0.5" onChange="setAEParameters();" class="input_numeric"/>
<span>%</span>
</div>
</div>
</div>
<div class="settings_row">
<div class="settings_cell_rb" style="vertical-align: middle;">
<!-- <span id="idShowAexpFrameMain" style="border:1px solid black;"></span>
<span id="idShowAexpFrameNavigator" style="border:1px solid yellow;"></span> -->
<div id="idShowAexpFrameMain_LB" style="float:left;">Show selection</div>
<div id="idShowAexpFrameMain_CB" style="float:left; width:25; height:25;"></div>
<div id="idShowAexpFrameNavigator_CB" style="float:right;"> </div>
<div id="idShowAexpFrameNavigator_LB" style="float:right;vertical-align: middle;">Show selection</div>
</div>
</div>
</div>
</div>
<div id="idSettingsTabs_div5" style="position:absolute; left:0; top:24; width:256; ">
<div class="settings_table">
<div class="settings_row" >
<div id="idQuality_ALL" class="settings_cell_rnb" style="position:relative; width:256;">
<div id="idQuality_LB" style="float:left; left:0;top:0; width:100;" ></div>
<div style="float:right">
<div id="Quality_slIder" style="position:relative;width:150; height:25;" ></div></div></div></div>
<div id="idFlip_ALL" class="settings_row">
<div id="idFlip_ALL" class="settings_cell_rb">
<div id="idFlipHor_ALL" style="float:left;" >
<div id="idFlipHor_LBTN" class="float_icon"></div>
<div id="idFlipHor_CB" class="float_icon"></div>
</div>
<div id="idFlipVert_ALL" style="float:left;">
<div id="idFlipVert_LBTN" class="float_icon"></div>
<div id="idFlipVert_CB" class="float_icon"></div>
</div>
<!--
<div id="idColor_ALL" style="float:left;">
<div id="idColor_LBTN" class="float_icon"></div>
<div id="idColor_CB" class="float_icon"></div>
</div>
-->
<div id="idColor_ALL" style="float:right;">
<div id="idColor_LBTN" class="float_icon"></div>
<select name="ColorSelect" id="idColorSelect" onchange="updateColor();">
<option value="0">mono</option>
<option value="1">color</option>
<option value="2">jp46</option>
<option value="3">jp46dc</option>
<!-- <option value="4">color20</option>-->
<option value="5">jp4</option>
<option value="6">jp4dc</option>
<option value="7">jp4diff</option>
<option value="8">jp4hdr</option>
<option value="9">jp4diff2</option>
<option value="8">jp4hdr2</option>
<option value="8">mono4</option>
</select>
</div>
<!--
0 - mono6, monochrome (color YCbCr 4:2:0 with zeroed out color componets)`
1 - color, YCbCr 4:2:0, 3x3 pixels`
2 - jp46 - original jp4, encoded as 4:2:0 with zeroed color components`
3 - jp46dc, modified jp46 so each color component uses individual DC diffenential encoding`
4 - reserved for color with 5x5 conversion (not yet implemented)`
5 - jp4 with ommitted color components (4:0:0)`
6 - jp4dc, similar to jp46dc encoded as 4:0:0`
7 - jp4diff, differential where (R-G), G, (G2-G) and (B-G) components are encoded as 4:0:0`
8 - jp4hdr, (R-G), G, G2,(B-G) are encoded so G2 can be used with high gain`
9 - jp4diff2, (R-G)/2, G,(G2-G)/2, (B-G)/2 to avoid possible overflow in compressed values`
10 - jp4hdr2, (R-G)/2, G,G2,(B-G)/2`
14 - mono, monochrome with ommitted color components (4:0:0)"</COLOR>
-->
<!--
<div id="id_ALL" style="float:right;">
<div id="idIgnoreStreamer_LB" class="float_icon"></div>
<div id="idIgnoreStreamer_CB" class="float_icon"></div>
</div>
-->
</div>
</div>
</div>
<div class="settings_table">
<!--MultiSensor -->
<div class="settings_row">
<div id="idMultiSensor_LB" class="settings_cell_rb">
</div>
</div>
<div class="settings_row">
<div id="idMultiSensor1" class="settings_cell_rnb">
<!-- formatting below is intentional - to avoid white spaces outside the tags -->
<span id="idMultiSensor10_out"><span id="idMultiSensor10"
>&nbsp;&nbsp;&nbsp;</span></span><span id="idMultiSensor11_out"><span id="idMultiSensor11"
>1</span></span><span id="idMultiSensor12_out"><span id="idMultiSensor12"
>2</span></span><span id="idMultiSensor13_out"><span id="idMultiSensor13"
>3</span></span>
</div>
</div>
<div class="settings_row">
<div id="idMultiSensor2" class="settings_cell_rnb">
<span id="idMultiSensor20_out"><span id="idMultiSensor20"
>X</span></span><span id="idMultiSensor21_out"><span id="idMultiSensor21"
>1</span></span><span id="idMultiSensor22_out"><span id="idMultiSensor22"
>2</span></span><span id="idMultiSensor23_out"><span id="idMultiSensor23"
>3</span></span>
</div>
<div id="idMultiSensorMode" class="settings_cell_rnb">
<span id="idMultiSensorModeM_out"><span id="idMultiSensorModeM"
>M</span></span><span id="idMultiSensorMode1_out"><span id="idMultiSensorMode1"
>1</span></span><span id="idMultiSensorMode2_out"><span id="idMultiSensorMode2"
>2</span></span><span id="idMultiSensorMode3_out"><span id="idMultiSensorMode3"
>3</span></span>
</div>
</div>
<div class="settings_row">
<div id="idMultiSensor3" class="settings_cell_rnb">
<span id="idMultiSensor30_out"><span id="idMultiSensor30"
>X</span></span><span id="idMultiSensor31_out"><span id="idMultiSensor31"
>1</span></span><span id="idMultiSensor32_out"><span id="idMultiSensor32"
>2</span></span><span id="idMultiSensor33_out"><span id="idMultiSensor33"
>3</span></span>
</div>
</div>
<!--/MultiSensor -->
<div class="settings_row">
<div id="idDCMhor_LB" class="settings_cell_rb">
</div>
</div>
<div class="settings_row">
<div id="idDCMhor" class="settings_cell_rnb">
<!-- formatting below is intentional - to avoid white spaces outside the tags -->
<span id="idDCMhor1_out"><span id="idDCMhor1"><span id="idDCMhor1_i18n"
>full</span></span></span><span id="idDCMhor2_out"><span id="idDCMhor2"
>1/2</span></span><span id="idDCMhor3_out"><span id="idDCMhor3"
>1/3</span></span><span id="idDCMhor4_out"><span id="idDCMhor4"
>1/4</span></span><span id="idDCMhor5_out"><span id="idDCMhor5"
>1/5</span></span><span id="idDCMhor6_out"><span id="idDCMhor6"
>1/6</span></span><span id="idDCMhor7_out"><span id="idDCMhor7"
>1/7</span></span><span id="idDCMhor8_out"><span id="idDCMhor8"
>1/8</span></span>
</div>
</div>
<div class="settings_row">
<div id="idDCMvert_LB" class="settings_cell_rb">
</div>
</div>
<div class="settings_row">
<div id="idDCMvert" class="settings_cell_rnb">
<span id="idDCMvert1_out"><span id="idDCMvert1"><span id="idDCMvert1_i18n"
>full</span></span></span><span id="idDCMvert2_out"><span id="idDCMvert2"
>1/2</span></span><span id="idDCMvert3_out"><span id="idDCMvert3"
>1/3</span></span><span id="idDCMvert4_out"><span id="idDCMvert4"
>1/4</span></span><span id="idDCMvert5_out"><span id="idDCMvert5"
>1/5</span></span><span id="idDCMvert6_out"><span id="idDCMvert6"
>1/6</span></span><span id="idDCMvert7_out"><span id="idDCMvert7"
>1/7</span></span><span id="idDCMvert8_out"><span id="idDCMvert8"
>1/8</span></span>
</div>
</div>
<div class="settings_row">
<div id="idBINhor_LB" class="settings_cell_rb">
</div>
</div>
<div class="settings_row">
<div id="idBINhor" class="settings_cell_rnb">
<span id="idBINhor1_out"><span id="idBINhor1"><span id="idBINhor1_i18n"
>full</span></span></span><span id="idBINhor2_out"><span id="idBINhor2"
>1/2</span></span><span id="idBINhor3_out"><span id="idBINhor3"
>1/3</span></span><span id="idBINhor4_out"><span id="idBINhor4"
>1/4</span></span><span id="idBINhor5_out"><span id="idBINhor5"
>1/5</span></span><span id="idBINhor6_out"><span id="idBINhor6"
>1/6</span></span><span id="idBINhor7_out"><span id="idBINhor7"
>1/7</span></span><span id="idBINhor8_out"><span id="idBINhor8"
>1/8</span></span>
</div>
</div>
<div class="settings_row">
<div id="idBINvert_LB" class="settings_cell_rb">
</div>
</div>
<div class="settings_row">
<div id="idBINvert" class="settings_cell_rnb">
<span id="idBINvert1_out"><span id="idBINvert1"><span id="idBINvert1_i18n"
>full</span></span></span><span id="idBINvert2_out"><span id="idBINvert2"
>1/2</span></span><span id="idBINvert3_out"><span id="idBINvert3"
>1/3</span></span><span id="idBINvert4_out"><span id="idBINvert4"
>1/4</span></span><span id="idBINvert5_out"><span id="idBINvert5"
>1/5</span></span><span id="idBINvert6_out"><span id="idBINvert6"
>1/6</span></span><span id="idBINvert7_out"><span id="idBINvert7"
>1/7</span></span><span id="idBINvert8_out"><span id="idBINvert8"
>1/8</span></span>
</div>
</div>
</div>
</div> <!-- end of tab 5 -->
<div id="idSettingsTabs_div6" style="position:absolute; left:0; top:24; width:256;">
<div id="idEnableHistAll" class="settings_item">
<span id="idEnableHist_LB" style="float:left;"></span>
<div id="idEnableHist_CB" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idHistHeightAll" class="settings_item">
<span id="idHistHeight_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idHistHeight_TX" size="5" value=""
onchange="updateHistControls();" class="input_numeric"/>
</span>
</div>
<div id="idHistAverAll" class="settings_item">
<span id="idHistAver_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idHistAver_TX" size="5" value=""
onchange="updateHistControls();" class="input_numeric"/>
</span>
</div>
<div id="idHistScaleAll" class="settings_item">
<span id="idHistScale_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idHistScale_TX" size="5" value=""
onchange="updateHistControls();" class="input_numeric"/>
</span>
</div>
<div id="idHistLinSqrtAll" class="settings_item">
<span id="idHistLin"><span id="idHistLin_i18n"></span></span>
<span id="idHistSqrt"><span id="idHistSqrt_i18n"></span></span>
</div>
<div id="idHistColors" class="settings_item">
<span id="idHistColorsR">R</span>
<span id="idHistColorsG">G</span>
<span id="idHistColorsB">B</span>
<span id="idHistColorsW">W</span>
<span id="idHistColorsG1">G1</span>
<span id="idHistColorsG2">G2</span>
</div>
<div id="idHistStyle" class="settings_item">
<span id="idHistStyleDots"><span id="idHistStyleDots_i18n"></span></span>
<span id="idHistStyleLine"><span id="idHistStyleLine_i18n"></span></span>
<span id="idHistStyleFilled"><span id="idHistStyleFilled_i18n"></span></span>
</div>
<div id="idHistInterp" class="settings_item">
<span id="idHistInterpGaps"><span id="idHistInterpGaps_i18n"></span></span>
<span id="idHistInterpSteps"><span id="idHistInterpSteps_i18n"></span></span>
<span id="idHistInterpLin"><span id="idHistInterpLin_i18n"></span></span>
</div>
</div>
<div id="idSettingsTabs_div7" style="position:absolute; left:0; top:24; width:256;">
<div id="idUpgradeAll" class="settings_item">
<span id="idUpgrade_LB" style="float:left;"></span>
<div id="idUpgrade_BN" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idSoftResetAll" class="settings_item">
<span id="idSoftReset_LB" style="float:left;"></span>
<div id="idSoftReset_BN" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idSensorResetAll" class="settings_item">
<span id="idSensorReset_LB" style="float:left;"></span>
<div id="idSensorReset_BN" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idTimeoutCmdAll" class="settings_item">
<span id="idTimeoutCmd_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idTimeoutCmd_TX" size="5" value="5000" onchange="timeoutsChanged();" class="input_numeric"/>
</span>
</div>
<div id="idTranspTooltipsAll" class="settings_item">
<span id="idTranspTooltips_LB" style="float:left;"></span>
<div id="idTranspTooltips_CB" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idTimeoutStatAll" class="settings_item">
<span id="idTimeoutStat_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idTimeoutStat_TX" size="5" value="5000" onchange="timeoutsChanged();" class="input_numeric"/>
</span>
</div>
<div id="idTimeoutAecmdAll" class="settings_item">
<span id="idTimeoutAecmd_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idTimeoutAecmd_TX" size="5" value="5000" onchange="timeoutsChanged();" class="input_numeric"/>
</span>
</div>
<div id="idTimeoutAestatAll" class="settings_item">
<span id="idTimeoutAestat_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idTimeoutAestat_TX" size="5" value="5000" onchange="timeoutsChanged();" class="input_numeric"/>
</span>
</div>
<div id="idTimeoutImgAll" class="settings_item">
<span id="idTimeoutImg_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idTimeoutImg_TX" size="5" value="5000" onchange="timeoutsChanged();" class="input_numeric"/>
</span>
</div>
<div id="idTimeoutHistAll" class="settings_item">
<span id="idTimeoutHist_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idTimeoutHist_TX" size="5" value="5000" onchange="timeoutsChanged();" class="input_numeric"/>
</span>
</div>
<div id="idTimeoutQuarAll" class="settings_item">
<span id="idTimeoutQuar_LB" style="float:left;"></span>
<span style="float:right;">
<input type="text" onmousedown="this.select()" id="idTimeoutQuar_TX" size="5" value="5000" onchange="timeoutsChanged();" class="input_numeric"/>
</span>
</div>
<div id="idSetDebugHelpAll" class="settings_item">
<span id="idSetDebugHelp" style="float:left;"></span>
<div id="idSetDebugHelp_CB" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idSetDebugRequestsAll" class="settings_item">
<span id="idSetDebugRequests" style="float:left;"></span>
<div id="idSetDebugRequests_CB" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idSetDebugOtherAll" class="settings_item">
<span id="idSetDebugOther" style="float:left;"></span>
<span style="float:right;">
<!-- <input type="text" onmousedown="this.select()" id="idSetDebugOther_TX" size="5" value="0"
onchange="document.title='';document.debug=parseInt(document.getElementById(this.id).value); showWindow();"
onmousedown="document.title='';debugWindowShow(document.getElementById('idCommStat_ALL').innerHTML);" class="input_numeric"/>-->
<input type="text" onmousedown="this.select()" id="idSetDebugOther_TX" size="5" value="0"
onchange="document.title='';document.debug=parseInt(document.getElementById(this.id).value); showWindow();"
onmousedown="document.title='';" class="input_numeric"/> </span>
</div>
<div id="idDumpTitleAll" class="settings_item">
<span id="idDumpTitle_LB" style="float:left;">Dump title text</span>
<div id="idDumpTitle_BN" style="float:right; width:25; height:25;" ></div>
</div>
<div id="idTest1" class="settings_item">
<span id="idTest1_LB" style="float:left;">test1 </span>
<div id="idTest1_BN" style="float:right; width:25; height:25;" ></div>
</div>
</div>
</div>
<div id="idUpgrade" style="display:none;position:absolute;left:256;top:0;width:512;height:256;z-index:49">
<div id="idUpgrade_iframe">
</div>
</div>
<div id="idTooltips" style="position:absolute;z-index:50;"> <!-- --> </div>
</div>
<a href="#" id="idLastQuery" target="_blank"></a>
<!-- DIVS as a database of messages accessible by id -->
<div id="idContextHelp" style="display:none"> </div>
<div id="reload"></div> <!-- just dummy div to exist with this ID -->
<div id="slIder"></div> <!-- just dummy div to exist with this ID -->
<div id="frAmesel"></div> <!-- just dummy div to exist with this ID -->
<div id="idCameraBusy"></div>
<div id="idStreamerRunning"></div>
<div id="idCCAMProblem"></div>
<div id="idCCAMErr"></div>
<div id="idPixel">pix</div>
<div id="idMore"></div>
<div id="idLess"></div>
<div id="idShiftWarn"></div>
<div id="idTitle"></div>
<div id="idUpgradeText"></div>
<div id="idUpgradeFirmware_LB"></div>
<div id="idUpgradeCancel_BN"></div>
<!--<div id="idtUpgradeNote"></div>-->
<div id="idUpgradeNoFile"></div>
<div id="idDVRServerInstall"></div>
</body>
</html>
This source diff could not be displayed because it is too large. You can view the blob instead.
<html>
<!--
*! -----------------------------------------------------------------------------**
*! camvcUpgrade.html
*!
*! Copyright (C) 2005-2007 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvcUpgrade.html,v $
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.1.1.1 2007/09/19 04:51:17 elphel
*! This is a fresh tree based on elphel353-2.10
*!
*! Revision 1.2 2007/09/19 04:51:17 elphel
*! Upgraded license (header)
*!
*!
-->
<head>
<title>Elphel NC333L firmware upgrade</title>
<script language="JavaScript" type="text/javascript">
<!--
function checkUpgrade() {
var form = document.UpgradeForm
if(form.fimage.value == "") {
alert(parent.document.getElementById("h_idUpgradeNoFile").innerHTML);
return;
}
window.setTimeout("document.UpgradeForm.submit()", 1000);
}
function initUpgrade() {
document.getElementById("idUpgradeTextI").innerHTML=parent.document.getElementById("h_idUpgradeText").innerHTML;
document.getElementById("idUpgradeFirmware_LBI").innerHTML=parent.document.getElementById("h_idUpgradeFirmware_LB").innerHTML;
document.getElementById("idUpgrade_BNI").value=parent.document.getElementById("h_idUpgrade_BN").innerHTML;
document.getElementById("idUpgradeCancel_BNI").value=parent.document.getElementById("h_idUpgradeCancel_BN").innerHTML;
}
function cancelUpgrade() {
parent.createUpgradeIframe(false);
}
// -->
</script>
</head>
<body onload="initUpgrade()">
<form name="UpgradeForm" action="/axis-cgi/admin/flash?-t+flash_all+-m+HTTP_POST" enctype="multipart/form-data" method="post">
<span id="idUpgradeTextI"></span>
<span id="idUpgradeFirmware_LBI"></span>&nbsp;<input type="file" name="fimage" value="fimage"/><br/><input type="button" id="idUpgrade_BNI" name="Upgrade" value="Upgrade" onClick="checkUpgrade()">&nbsp;
<input type="button" id="idUpgradeCancel_BNI" name="UpgradeCancel" value="Cancel" onClick="cancelUpgrade()">
</form>
</body>
</html>
/*
*! -----------------------------------------------------------------------------**
*! FILE NAME : camvc_camcomm.js
*! DESCRIPTION: Provides communication with the camera
*! Copyright (C) 2008 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvc_camcomm.js,v $
*! Revision 1.18 2010/08/01 19:30:24 elphel
*! new readonly parameter FRAME_SIZE and it support in the applications
*!
*! Revision 1.17 2010/06/04 01:56:51 elphel
*! Initial support for the multi-sensor operation
*!
*! Revision 1.16 2008/12/11 07:24:35 elphel
*! debug output (commented out anyway)
*!
*! Revision 1.15 2008/12/11 06:37:57 elphel
*! Added animated refresh button
*!
*! Revision 1.14 2008/12/10 22:09:37 elphel
*! Skipping histogram refresh (and hiding it) when compressor is stopped (fro circbuf navigation)
*!
*! Revision 1.13 2008/12/10 07:25:12 elphel
*! fixing bugs that prevented this page work with Konqueror
*!
*! Revision 1.12 2008/12/10 03:43:17 elphel
*! Bug fix that prevented Konqueror to open camvc. Now it nearly works with it
*!
*! Revision 1.11 2008/12/09 23:35:38 elphel
*! Fixed handling Exif image description
*!
*! Revision 1.10 2008/12/09 22:11:56 elphel
*! Fixed resizing, changed color/mono checkbox to mode selector
*!
*! Revision 1.9 2008/12/09 07:51:52 elphel
*! Partial support of ccam.ftp added alerts on non-yet-ported control tabs. Temporary launches autocampars to save selected parameters fro next autostart
*!
*! Revision 1.8 2008/12/08 22:19:17 elphel
*! removed obsolete parts of ccamftp software
*!
*! Revision 1.7 2008/12/05 08:10:19 elphel
*! Fixed work (at least seems so) circbuf+Exif operation
*!
*! Revision 1.6 2008/12/05 03:31:31 elphel
*! Multiple changes, some cleanup and working on restoring circbuf/Exif functionality available in 7.1
*!
*! Revision 1.5 2008/12/04 02:24:46 elphel
*! Adding/debugging autoexposure controls
*!
*! Revision 1.4 2008/12/02 00:28:13 elphel
*! multiple bugfixes, making white balance to work and work with camvc
*!
*! Revision 1.3 2008/12/01 07:33:03 elphel
*! Added gains, scales, white balance control
*!
*! Revision 1.2 2008/11/30 06:41:43 elphel
*! changed default IP back to 192.168.0.9 (temporarily was 192.168.0.7)
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.4 2008/11/16 17:35:53 elphel
*! restored histogram (autoexposure) window control
*!
*! Revision 1.3 2008/11/10 19:55:51 elphel
*! 8.0.alpha15 - first camvc working with 8.0 (just basic features - no autoexposure, white balance, ...), but it is now really possible (again after it was broken for quite a while) to move sliders and navigator windows without fighting with the camera that tried to move them back
*!
*! Revision 1.2 2008/11/08 23:59:23 elphel
*! snapshot
*!
*! Revision 1.1 2008/11/08 05:54:02 elphel
*! snapshot - working on camvc
*!
*!
*/
document.cameraParametersAcquired=false; /// not used so far
var gNoMoreAlerts=false; //to prevent endless alert_onces
/// States of the parameters that er needed to be synchronized between the client and th camera
var STATE_DISABLED= 0; /// client is not yet synchronized with the camera, no client-initiated parameters changes are permitted
/// (until got parameters from the camera)
var STATE_DISABLED1= 1; /// client is in the process of synchronizing with the camera (received once), to client-initiated parameters changes are permitted
/// (until got parameters from the camera)
var STATE_IDLE= 2; /// Parameter was not modified by user (at least since it was updated from the camera) - only state for readonly parameters
var STATE_CLIENTMOD= 3; /// Parameter was modified by user, no related request sent to the camera yet
var STATE_REQUESTSENT=4; /// Request to modify the parameter was sent to the camera (timestamp of the request assigned parameter.timestamp
var STATE_REQUESTCONF=5; /// Request to modify the parameter was confirmed by the camera, parameter.target_frame assigned
/// Request states
var COMM_STATE_INIT= 0; /// not yet initialized
var COMM_STATE_IDLE= 1; /// initial state (send commands/request status)
var COMM_STATE_CMD= 2; /// command sent/status request sent, waiting for xmlresponse
var COMM_STATE_IMG= 3; /// image request sent, waiting for the image
var COMM_STATE_HIST= 4; /// histogram request sent, waiting for the histogram
var COMM_STATE_LAST= COMM_STATE_HIST; /// last state
/// sequence of actions matters
var camParamsList=Array (
{name:"sensor", type:"s", act:"onSensor", delay:0},
{name:"SENSOR", type:"i", act:"onSensor", delay:0},
{name:"SENSOR_WIDTH", type:"i", act:"onSensor", delay:0},
{name:"SENSOR_HEIGHT", type:"i", act:"onSensor", delay:0},
{name:"e", type:"f", act:"onGotExposure", delay:0},
{name:"color", type:"i", act:"onGotColor", delay:0},
{name:"fliph", type:"i", act:"onGotWindow", delay:0},
{name:"flipv", type:"i", act:"onGotWindow", delay:0},
{name:"ww", type:"i", act:"onGotWindow", delay:0},
{name:"wh", type:"i", act:"onGotWindow", delay:0},
{name:"wl", type:"i", act:"onGotWindow", delay:0},
{name:"wt", type:"i", act:"onGotWindow", delay:0},
{name:"dh", type:"i", act:"onGotWindow", delay:0},
{name:"dv", type:"i", act:"onGotWindow", delay:0},
{name:"bh", type:"i", act:"onGotWindow", delay:0},
{name:"bv", type:"i", act:"onGotWindow", delay:0},
{name:"msens", type:"i", act:"onSensor", delay:0},
{name:"mseq", type:"i", act:"onGotWindow", delay:0},
{name:"mmod", type:"i", act:"onGotWindow", delay:0},
{name:"msel", type:"i", act:"onGotWindow", delay:0},
{name:"ACTUAL_WIDTH", type:"i", act:"onGotWindow", delay:0},
{name:"ACTUAL_HEIGHT", type:"i", act:"onGotWindow", delay:0},
{name:"FRAME_SIZE", type:"i", act:"onGotWindow", delay:0},
{name:"iq", type:"i", act:"onGotQuality", delay:0},
{name:"gr", type:"f", act:"onGotGains", delay:0},
{name:"gg", type:"f", act:"onGotGains", delay:0},
{name:"ggb", type:"f", act:"onGotGains", delay:0},
{name:"gb", type:"f", act:"onGotGains", delay:0},
{name:"rscale", type:"f", act:"onGotScales", delay:0},
{name:"bscale", type:"f", act:"onGotScales", delay:0},
{name:"gscale", type:"f", act:"onGotScales", delay:0},
{name:"wbrs", type:"f", act:"onGotWbScales", delay:0},
{name:"wbbs", type:"f", act:"onGotWbScales", delay:0},
{name:"wbgs", type:"f", act:"onGotWbScales", delay:0},
{name:"wben", type:"i", act:"onGotWbEn", delay:0}, // change to wb
{name:"bit", type:"i", act:"onGotBit", delay:0},
{name:"gam", type:"f", act:"onGotGammaPxl", delay:0, linked:Array("pxl")},
{name:"pxl", type:"f", act:"onGotGammaPxl", delay:0, linked:Array("gam")},
{name:"csb", type:"f", act:"onGotSaturation", delay:0},
{name:"csr", type:"f", act:"onGotSaturation", delay:0},
{name:"comp_run", type:"s", act:"onCompSensRun", delay:0},
{name:"sens_run", type:"s", act:"onCompSensRun", delay:0},
{name:"fps", type:"f", act:"onFPS", delay:0},
{name:"fpslm", type:"f", act:"onFPS", delay:0},
{name:"fpsflags", type:"i", act:"onFPS", delay:0},
///TODO: Make some parameters only sent on startup?
{name:"decXmask", type:"i", act:"onSensor", delay:0},
{name:"decYmask", type:"i", act:"onSensor", delay:0},
{name:"binXmask", type:"i", act:"onSensor", delay:0},
{name:"binYmask", type:"i", act:"onSensor", delay:0},
{name:"hrw", type:"f", act:"onHistWnd", delay:0},
{name:"hrh", type:"f", act:"onHistWnd", delay:0},
{name:"hrl", type:"f", act:"onHistWnd", delay:0},
{name:"hrt", type:"f", act:"onHistWnd", delay:0},
{name:"ae", type:"s", act:"onAexpOnOff", delay:0},
{name:"aef", type:"f", act:"onAexp", delay:0},
{name:"ael", type:"f", act:"onAexp", delay:0},
{name:"aemax", type:"f", act:"onAexpMaxExp",delay:0},
{name:"ftp", type:"s", act:"onFTPOnOff", delay:0}
);
var gPRoot={};
var gRequests;
var gXML_req={}; //has to be global?
function initParams(list) {
var i;
gRequests= new Requests();
for (i in list) {
gPRoot[list[i].name] = new CamAPar (list[i].name,list[i].type, list[i].act,list[i].delay,list[i].linked);
gRequests.addAction (list[i].act);
}
}
/// =============== constructor for Requests ======================
function Requests() {
this.timeout= 10000; /// 20 seconds - may increase for the slow internet connections
this.timeOutTimerID= null;
this.updateStatTimerID=null; /// once-a-second status update
this.updateStatPeriod= 1000; /// update status while waiting for request
this.lastRequestSent= 0;
this.refreshDuration= 20000;
this.refreshTimeOut= 0;
// this.completed= true; /// will be set to false by timout timer
this.maxRetries= 2;
this.retriesLeft= 2;
this.inProgress= false;
this.state=COMM_STATE_INIT;
this.cmdNeeded=0; /// reset when all actions are processed and allcamAPar.state==STATE_IDLE. Allow other requests (image, histogram) to proceed
this.cmdRequsted=0; ///value of cmdNeeded when request was sent (do detect any parameters set between request sent and received)
this.setStr='';
this.getStr='';
this.todo={};
this.time=new Date();
this.timestamp=this.time.getTime();
this.actions={};
this.php='camvc.php';
// this.histogram="/pnghist.cgi?";
this.histogram='/pnghist.cgi?';
this.imgsrv=""; /// will be received from the camera - like http://192.168.0.9:8081/
this.url='';
this.imgUrl='bimg';
this.histUrl='';
// this.extraParameters='&out=all&dbgwait&sleep=2';
// this.extraParameters='&out=all&dbgwait';
this.extraParameters='&out=all';
this.setTimeImage=new Image();
var t1=new Date();
this.setTimeImage.src=this.php+'?out=gif&_time='+t1.getTime(); // just set FPGA/system time (if was not set before)
this.ExifPage=0; // 0 - current. else (stopped) - match current image
this.pointersAreCurrent=false; // acquire circbuf pointers after compressor is stopped
this.pointersAreNeeded= true;
this.circbuf=Array();
this.circbuf_count=0;
this.circbufNavigationPendingId="";
this.circbuf_fp="";
this.circbuf_frame_number=0;// (0 - latest, 1...this.circbuf_count - from buffer)
this.ExifNeeded=false;
this.ExifCircbufImgNeeded=false;
this.newDescription="";
this.bgHist=new Image();
this.shadowImage= new Image();
this.emptyImg=new Image();
this.emptyImg.src='/images/empty.png';
// this.shadowImage.onload=gInterface.gotShadow;
// this.bgHist.onload= gInterface.gotHistogram;
document.debug=0;
this.numRequests={cmd:0,img:0,hist:0}; //not yet used
// this.actualWidth=0;
// this.actualHeight=0;
this.lastImageWidth=1;
this.lastImageHeight=1;
document.imageEnabled=true;
document.awbFlag=true;
document.histogramEnabled=true;
document.imageGot=false;
document.userFPS=30; ///FIXME:
document.hist={
enabled:1,
hght:128,
aver:5,
scale:1.0,
sqr:1,
r:1,g:1,b:1,w:0,g1:0,g2:0,
stl:1,
interp:2};
/// document.hist_out={hist_out_r:0,hist_out_g:0,hist_out_g2:0,hist_out_b:0};
/// document.hist_in={hist_in_r:0,hist_in_g:0,hist_in_g2:0,hist_in_b:0};
};
Requests.prototype.needsUpdate=function() {
this.cmdNeeded++;
}
Requests.prototype.setInterfacePointers=function(onloadImage,onloadHistogram) {
this.shadowImage.onload=onloadImage;
this.bgHist.onload= onloadHistogram;
}
function pressedRefresh(force) {
dbgp(4," RFR"+gRequests.state+"(force="+force+")");
if (force) {
alert ("Ignoring current activity, resetting state to COMM_STATE_IDLE. (state was "+gRequests.state+")");
gRequests.state=COMM_STATE_IDLE;
}
startRefresh();
}
function startRefresh() {
//document.title+=gRequests.state+"--"+gRequests.inProgress+"//"; //1--
if (document.debug & 32768) document.title+="#";
gRequests.needsUpdate();
var t=new Date();
gRequests.refreshTimeOut=t.getTime()+ gRequests.refreshDuration; // start the refresh/timeout
if (((gRequests.state==COMM_STATE_IDLE) || (gRequests.state==COMM_STATE_INIT)) && !gRequests.inProgress) {
// document.title+="%%";
requestsNextState(gRequests.state==COMM_STATE_IDLE); // start from idle
// document.title+="+++";
}
}
/// start with (state==COMM_STATE_INIT) requestsNextState(false) - it will "retry" initialization
//Requests.prototype.nextState=function(success) {
function requestsNextState(success) {
//document.title="=="+gRequests.state+"("+success+")";
//document.title+=' '+gRequests.state;
gRequests.inProgress= false;
gRequests.clearTimeouts();
stopRequestsStatusUpdateTimer();
if (!success) {
/// abort any requests in progress
if (gXML_req && (typeof(gXML_req.abort) == "function")) gXML_req.abort(); /// Aborting XML request (if any)
/// Add aborting image/histogram here
if (gRequests.state==COMM_STATE_IMG) gRequests.shadowImage.src=gRequests.emptyImg.src; /// hope there will be no onLoad!
else if (gRequests.state==COMM_STATE_HIST) gRequests.bgHist.src= gRequests.emptyImg.src;
gRequests.retriesLeft--;
if (gRequests.retriesLeft<0) {
gInterface.statusUpdate();
gRequests.state= COMM_STATE_IDLE;
alert ("Aborted as retry counter expired");
return; /// ****** will stop updating.
}
} else { /// Previous request was a success. Need to go to the next one
switch (gRequests.state) { /// current state
case COMM_STATE_INIT: /// Here - after first successfully received status data from the camera
circbufRun(gPRoot["comp_run"].getValue() == 'run');
gRequests.state= COMM_STATE_CMD;
break;
case COMM_STATE_IDLE: /// What was that? Just awaken
gRequests.state= COMM_STATE_CMD;
break;
case COMM_STATE_CMD:
if (gRequests.cmdNeeded) gRequests.state= COMM_STATE_CMD; /// Need to send command/get status now
else gRequests.state= COMM_STATE_IMG;
break;
/// requests for Image and histogram will return to the requestsNextState(true) - they check conditions there
case COMM_STATE_IMG:
if (gRequests.cmdNeeded) gRequests.state= COMM_STATE_CMD; /// Need to send command/get status now
else gRequests.state= COMM_STATE_HIST;
break;
case COMM_STATE_HIST:
if (gRequests.cmdNeeded) gRequests.state= COMM_STATE_CMD; /// Need to send command/get status now
else { /// see if the refresh time expired
// gRequests.state= COMM_STATE_CMD;
gRequests.state= COMM_STATE_IDLE;
}
break;
}
/// find out - what will be the next state
gRequests.retriesLeft=gRequests.maxRetries;
}
/// See if restart is needed
var t=new Date();
/// writing small numbers to gRequests.refreshTimeOut will cause that number of update cycles to run, then stop
if (gRequests.state == COMM_STATE_IDLE) {
//document.title="*"+(gRequests.refreshTimeOut-t.getTime())+"*";
if ( gRequests.cmdNeeded ||
((gPRoot["comp_run"].getValue() == 'run')?
(gRequests.refreshTimeOut > t.getTime()):
(!gRequests.pointersAreCurrent && gRequests.pointersAreNeeded))) {
gRequests.state= COMM_STATE_CMD;
}
//document.title+="("+gRequests.state+")";
}
/// for all states, but idle
if (gRequests.state!= COMM_STATE_IDLE) {
gRequests.clearTimeouts(); // just in case
gRequests.timeOutTimerID=setTimeout(requestsNextState, gRequests.timeout,false);
startRequestsStatusUpdateTimer();
}
// var t=new Date();
gRequests.lastRequestSent=t.getTime();
switch (gRequests.state) { /// send next request...
case COMM_STATE_IDLE: /// will stop refreshing
break;
case COMM_STATE_INIT: /// see if
case COMM_STATE_CMD:
gRequests.sendHttpReq(); /// Will trigger either requestsNextState(true) or requestsNextState(false)
break;
case COMM_STATE_IMG:
gRequests.getImage();
/// start image loading, onLoad/timeout should trigger either requestsNextState(true) or requestsNextState(false)
break;
case COMM_STATE_HIST:
gRequests.getHistogram();
/// start histogram loading, onLoad/timeout should trigger either requestsNextState(true) or requestsNextState(false)
break;
}
return;
// }
}
Requests.prototype.clearTimeouts=function() {
if (this.timeOutTimerID) { /// Clear it in any case - timeout or not
clearTimeout(this.timeOutTimerID);
this.timeOutTimerID=null; /// stop timer
}
}
/**
* @brief Prepare and send HTTP request
*/
Requests.prototype.sendHttpReq=function() {
this.time=new Date(); ///only for parameters request
this.timestamp=this.time.getTime();
this.prepGetStr();
this.prepTodo();
this.serialize();
this.url=this.php+"?";
this.cmdRequsted=this.cmdNeeded; ///value of cmdNeeded when request was sent (do detect any parameters set between request sent and received)
if (this.setStr.length) {
this.url+="set="+this.setStr+"&";
}
this.url+="get="+this.getStr;
// this.url+="&hout="+((gPRoot['ae'].getValue()=='on')?(document.AeLevelToDisplay/256):gPRoot['ael'].getValue());
// this.url+="&hout="+((gPRoot['ae'].getValue()=='on')?(parseFloat(getSliderValue("idAexpMonitor_slIder"))/256):gPRoot['ael'].getValue());
this.url+="&hout="+muxHistLevel();
// if ((gPRoot['comp_run'].getValue()!='run') &&
//document.title+="("+this.pointersAreCurrent+":"+this.pointersAreNeeded+")";
if ((gPRoot['comp_run'].getValue()=='stop') &&
!this.pointersAreCurrent &&
this.pointersAreNeeded &&
(!(this.setStr.indexOf('comp_run')>=0))) { /// it is better to wait for the confirmation compressor is actually stopped. otherwise - too early
this.url+="&circbuf";
}
if (this.newDescription) {
this.url+="&description="+this.newDescription;
this.newDescription="";
}
if (gPRoot['comp_run'].getValue()=='run') this.url+="&exif=0";
else if (this.ExifNeeded) this.url+="&exif="+this.ExifPage;
// gPRoot['ael'].setValue(parseFloat(getSliderValue("idAexpLevels_slIder"))/256);
//getSliderValue("idAexpMonitor_slIder")
this.url+=this.extraParameters;
this.url+="&_time="+this.timestamp;
if (this.imgsrv=="") this.url+="&imgsrv";
checkBadUrl(this.url,"Requests.prototype.sendHttpReq");
gXML_req=new XMLHttpRequest();
gXML_req.open("GET", this.url, true);
gXML_req.reqObject = this;
gXML_req.onreadystatechange = function() { // "this" does not work here with Konqueror, but gXML_req.status still fails
if (typeof(gXML_req)=="undefined") return; /// trying to fight "uncaught exceptions" (happens when camera is setting it's date)
if (gXML_req.readyState == 4) {
if (((gXML_req.status >= 200) && (gXML_req.status < 300)) || (gXML_req.status ==304) ||
((typeof(gXML_req.status) =='undefined' ) && ((navigator.userAgent.indexOf("Safari")>=0) || (navigator.userAgent.indexOf("Konqueror")>=0))))
{ // if camera time was not set in advance, "uncaught exception" will be here
gXML_req.reqObject.parseXML(gXML_req.responseXML);
// requestsNextState(true); // **** back to the main loop: GOOD
} else {
if ((document.cameraParametersAcquired) || (gXML_req.status)) /// Status 0 is common when the page is reloaded with some request pending
if (gXML_req.status || document.cameraParametersAcquired) { /// Ignoring stray responces when page is reloaded
alert_once("There was a problem retrieving the XML data:\n" + (gXML_req.status?gXML_req.statusText:"gXML_req.status==0")+ ", document.cameraParametersAcquired="+document.cameraParametersAcquired+
"\nYou may safely ignore this message if you just reloaded this page");
}
}
}
}
gXML_req.send(null);
this.inProgress= true;
}
Requests.prototype.parseXML=function(xml) {
// gRequests.clearTimeouts();
// stopRequestsStatusUpdateTimer();
// document.title+=" D";
// document.title+="--> ";
if (this.cmdNeeded==this.cmdRequsted) this.cmdNeeded=0; /// No parameter changes/requests were made between xml request and responce
this.allPars={}; /// array of "abstarct" parameters/values received
this.allNatPars={}; /// array of native parameters/values received
this.allSet={};
// this.allSetXML=xml.getElementsByTagName('set'); // just for the fireBug - it sometimes nulls the xml structure
var iter, inat, setName;
var i, ep;
// var nativeGot=xml.getElementsByTagName('nativeGot');
if (xml.getElementsByTagName('nativeGot').length>0) {
for (iter= xml.getElementsByTagName('nativeGot')[0].firstChild; iter; iter=iter.nextSibling) this.allNatPars[iter.tagName]=parseInt(iter.firstChild.nodeValue);
}
if (xml.getElementsByTagName('get').length>0) {
for (iter= xml.getElementsByTagName('get')[0].firstChild; iter; iter=iter.nextSibling) this.allPars[iter.tagName]=iter.firstChild.nodeValue;
}
if (xml.getElementsByTagName('set').length>0) {
for (iter= xml.getElementsByTagName('set')[0].firstChild; iter; iter=iter.nextSibling) {
setName=iter.tagName;
this.allSet[setName]={};
if (iter.getElementsByTagName('frame').length>0) this.allSet[setName]['frame']=parseInt(iter.getElementsByTagName('frame')[0].firstChild.nodeValue);
this.allSet[setName]['native']={};
if (iter.getElementsByTagName('native').length>0) {
for (inat= iter.getElementsByTagName('native')[0].firstChild; inat; inat=inat.nextSibling) {
this.allSet[setName]['native'][inat.tagName]=(inat.firstChild==null)?null:inat.firstChild.nodeValue;
}
}
}
}
this.receivedFrame=this.allNatPars['FRAME'];
if ((xml.getElementsByTagName('req_ts').length>0) && (xml.getElementsByTagName('req_ts')[0].firstChild)) {
this.receivedTimestamp=parseInt(xml.getElementsByTagName('req_ts')[0].firstChild.nodeValue);
}
/// Process sent parameters confirmations
for (iter in this.allSet) {
gPRoot[iter].conf(this.receivedTimestamp, this.allSet[iter].frame, this.allSet[iter].native);
}
/// Process parameter chnages
for (iter in this.allPars) { //.receivedTimestamp is used to detect missing confirmation of the request sent
gPRoot[iter].received(this.receivedTimestamp, this.allPars[iter],this.receivedFrame,this.allNatPars);
}
///Receive circuf data if any
if ((xml.getElementsByTagName('circbuf').length>0) && (xml.getElementsByTagName('circbuf')[0].childNodes.length>0)) {
this.circbuf_count=xml.getElementsByTagName('circbuf')[0].childNodes.length;
this.circbuf=getCircbuf(xml.getElementsByTagName('circbuf')[0].childNodes);
this.pointersAreCurrent=true;
showCircbufFrame(this.circbuf_count);
//document.title+="pending:"+this.circbufNavigationPendingId+" ";
if (this.circbufNavigationPendingId!=="") {
pressedCircbufNav(this.circbufNavigationPendingId);
}
}
///Receive Exif data if any
// if ((gPRoot['comp_run'].getValue()!='on') && (parseInt( getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('Exif_page' )[0]) ) == this.ExifPage))
// this.ExifNeeded=false;
if ((xml.getElementsByTagName('Exif').length>0)) {
ep=parseExif(xml.getElementsByTagName('Exif')[0]); // calculate always!
if ((gPRoot['comp_run'].getValue()!='on') && (ep == this.ExifPage)) this.ExifNeeded=false;
}
///sent
this.doActions();
/// receive histogram data:
if ((xml.getElementsByTagName('hist_out_g').length>0) && (xml.getElementsByTagName('hist_out_g')[0].firstChild)) {
gInterface.onGotHistOutG(parseFloat(xml.getElementsByTagName('hist_out_g')[0].firstChild.nodeValue));
}
if ((this.imgsrv=="") && (xml.getElementsByTagName('imgsrv').length>0))
this.imgsrv= xml.getElementsByTagName('imgsrv')[0].firstChild.nodeValue;
if (!document.cameraParametersAcquired) {
parametersInitialized();
document.cameraParametersAcquired=true;
}
// btnRefresh
// setBuTtonState("idEnableHist_CB",true); /// hack - fighting control that slides out of the mouse when histogram window opens
// alert ("set to 1! - "+getBuTton('idEnableHist_CB').s);
// this.receivedFrame=this.allNatPars['FRAME'];
var refreshButtonState=getBuTton('btnRefresh').s;
if ((refreshButtonState!=1) && (refreshButtonState!=2)) { /// not pressed and not disabled
// setBuTtonState('btnRefresh',(4+(this.receivedFrame & 3)));
setBuTtonState('btnRefresh',(4+((refreshButtonState+1) & 3)));
}
requestsNextState(true); // **** back to the main loop: GOOD
}
function getIfDefinedFCNV(obj) {return (typeof(obj)!="undefined")?((obj.firstChild)?obj.firstChild.nodeValue:""):"";}
function getIfDefined0FCNV(obj) {return (obj.length && (typeof(obj[0])!="undefined"))?((obj[0].firstChild)?obj[0].firstChild.nodeValue:""):"";}
Requests.prototype.getImage=function() {
// if (!document.imageEnabled) { requestsNextState(true); return; } // **** back to the main loop: SKIPPED
if (getBuTton('idEnableImageRefresh_CB').s==0) { requestsNextState(true); return; } /// **** back to the main loop: SKIPPED
var t=new Date();
/// document.requests.img++; debugComm(8192);
if (gPRoot["comp_run"].getValue() == 'run'){
this.shadowImage.src= this.imgsrv+this.imgUrl+"&_time="+t.getTime();
// document.title+="bimg";
} else if (this.ExifCircbufImgNeeded) {
var newUrl=this.imgsrv+this.circbuf_fp+this.imgUrl;
//alert(newUrl+"---"+this.shadowImage.src);
if (newUrl==this.shadowImage.src) {
// alert ("--same image--");
requestsNextState(true); // **** back to the main loop: SKIPPED
return;
}
this.shadowImage.src= this.imgsrv+this.circbuf_fp+this.imgUrl;
// document.title+=this.circbuf_fp+"bimg";
} else {
// document.title+="#";
requestsNextState(true);
return;
} // **** back to the main loop: SKIPPED
this.inProgress= true;
}
Requests.prototype.getHistogram=function() {
//document.title="*****************"+getBuTton('idEnableHist_CB').s;
//document.title+='G';
// if (getBuTton('idEnableHist_CB').s==0) { requestsNextState(true); return; } /// **** back to the main loop: SKIPPED
if (document.getElementById("idDivHist").style.display == 'none') { requestsNextState(true); return; } /// **** back to the main loop: SKIPPED
// document.title+=" getHistogram()";
this.inProgress= true;
var t=new Date();
// document.requests.hist++; debugComm(8192);
// this.bgHist.src=this.histUrl+"&_time="+t.getTime(); ///hist.url should be prepared
this.bgHist.src=this.histUrl+"&_time="+t.getTime(); ///hist.url should be prepared
}
function startRequestsStatusUpdateTimer() {
stopRequestsStatusUpdateTimer(); // and update status on screen
gRequests.updateStatTimerID = self.setTimeout("startRequestsStatusUpdateTimer()", gRequests.updateStatPeriod);
}
function stopRequestsStatusUpdateTimer() {
if (gRequests.updateStatTimerID) {
clearTimeout(gRequests.updateStatTimerID);
gRequests.updateStatTimerID=null;
}
gInterface.statusUpdate();
}
Requests.prototype.addAction=function(act) {
this.actions[act]={frame:0,
needed:false,
func:null
};
var ev='this.actions["'+act+'"].func = function() {gInterface.'+act+'();};';
eval (ev);
}
Requests.prototype.scheduleAction=function(act,frame) {
if (this.actions[act].frame < frame) {
this.actions[act].frame = frame;
this.actions[act].needed =true;
}
}
Requests.prototype.doActions=function() {
var iAct;
for (iAct in this.actions) if (this.actions[iAct].needed) {
//document.title+=">>"+iAct+"<< ";
this.actions[iAct].func();
this.actions[iAct].needed =false;
}
var iPar;
for (iPar in gPRoot) gPRoot[iPar].clearNew(); // clear new flag for all parameters after they are used
}
/// Prepare serialized string to be sent as "&set=..."
Requests.prototype.prepGetStr=function() {
var par;
this.getStr="";
for (par in gPRoot) {
this.getStr+=gPRoot[par].getName()+"/";
}
};
/**
* @brief Prepare todo array (top indexes - relative delays in frames, below name/value pairs)
*/
Requests.prototype.prepTodo=function() { /// timestamp should be set
var par;
var lastDelay=0;
this.todo={};
for (par in gPRoot) {
if (gPRoot[par].reqToSend()) {
if (typeof(this.todo[gPRoot[par].getDelay()])=="undefined") this.todo[gPRoot[par].getDelay()]={};
this.todo[gPRoot[par].getDelay()][gPRoot[par].getName()]=gPRoot[par].getValue();
gPRoot[par].sent(this.timestamp);
}
}
};
Requests.prototype.serialize=function() {
var dly, par;
this.setStr="";
for (dly in this.todo) {
this.setStr+=dly+"/";
for (par in this.todo[dly]) {
this.setStr+=par+":"+this.todo[dly][par]+"/";
}
}
};
/// =============== constructor for CamAPar ======================
function CamAPar(name, varType, act, dly, linked) {
this.name=name;
this.varType=varType; // s - string, i - integer, f - float
this.sValue=""; // string value, before parsing
this.parValue=0; // parsed parameter value
this.timestamp=0;
this.frame=0;
this.relatedNative={};
// this.state=STATE_IDLE;
this.state=STATE_DISABLED;
this.delay=dly; // maybe will be needed
this.act=act;
this.newValue; /// when action was scheduled, this parameter was modified
// this.linked=(typeof(linked) != "undefined")?linked:Array();
this.linked=(linked)?linked:Array();
// eval ('this.act = function() {'+act+'();};');
}
CamAPar.prototype.isNew= function() {return this.newValue};
CamAPar.prototype.clearNew=function() {this.newValue=false};
CamAPar.prototype.getValue=function() {return this.parValue};
CamAPar.prototype.getName= function() {return this.name};
CamAPar.prototype.getDelay=function() {return this.delay};
CamAPar.prototype.getState=function() {return this.state};
CamAPar.prototype.setValue=function(val) {
var i;
var result=false;
//document.title+="setValue, this.state="+this.state+" this.name="+this.name+" val="+val;
//document.title="setValue, this.state="+this.state+" this.name="+this.name+" val="+val;
if ((this.state!=STATE_DISABLED) && (this.state!=STATE_DISABLED1) && (this.parValue!=val)) {
if (isBad(val)) alert ("this.state="+this.state+" setValue ("+val+":"+typeof(val)+"):"+this.toSource()); ///#####################################
if (isBad(val)) return false;
this.sValue=""+val;
//document.title+=this.name+":"+this.varType+" ";
switch (this.varType) {
case "i": this.parValue=parseInt (this.sValue); break;
case "f": this.parValue=parseFloat(this.sValue); break;
default: this.parValue=this.sValue;
}
if (isBad(this.parValue)) {
alert("val=>"+val+", this.parValue="+this.parValue+", this.name="+this.name);
}
//document.title=">>"+this.state+" val="+val;
// this.parValue=val;
this.state=STATE_CLIENTMOD;
for (i in this.linked) {
gPRoot[this.linked[i]].setValueModified();
}
result=true;
gRequests.needsUpdate();
}
startRefresh();
return result;
}
/// Set state as if the value was modified (for parameters that have to be sent together)
CamAPar.prototype.setValueModified=function() {
//document.title="setValue, this.state="+this.state+" this.name="+this.name+" val="+val;
var result=false;
if ((this.state!=STATE_DISABLED) && (this.state!=STATE_DISABLED1)) {
this.state=STATE_CLIENTMOD;
if (isBad(this.parValue)) {
alert("setValueModified: val=>"+val+", this.parValue="+this.parValue);
}
result=true;
gRequests.needsUpdate();
}
startRefresh();
return result;
}
CamAPar.prototype.setDelay=function(val) {
this.delay=val; // nothing else for now
}
CamAPar.prototype.reqToSend= function() {return this.state==STATE_CLIENTMOD;};
CamAPar.prototype.sent= function(ts) {
this.state=STATE_REQUESTSENT;
this.timestamp=ts;
}
CamAPar.prototype.conf= function(ts,frame,relNat) {
if (this.state!=STATE_REQUESTSENT) return false ; /// relying that cameras will always be re-requested for all paramer values?
if (ts==this.timestamp) {
this.relatedNative=relNat; /// array (usually just one element) of camera native parameters linked to the current "abstruct" one
this.frame=frame; /// target frame number when the parameters are expected to change in response to the command
this.state=STATE_REQUESTCONF; /// request confirmed, waiting for the value of the parameter from the specified (or later) frame
return true;
} else if (ts>this.timestamp) { /// the request to modify this parameter seems to be lost - re-send the request
this.state=STATE_CLIENTMOD;
return false;
}
return false; /// confirmation from the earlier request - disregard it
};
CamAPar.prototype.received= function(ts,val,frame,AllNatPars) {
// if (this.name="comp_run") document.title+="-2("+this.state+":"+val+"/"+this.relatedNative['COMPRESSOR_RUN']+":"+AllNatPars['COMPRESSOR_RUN']+")";
var key, modif;
switch (this.state) {
case STATE_REQUESTSENT: /// request sent, waiting (missed) confirmation
if (ts>this.timestamp) this.state=STATE_CLIENTMOD; /// resend request
return false;
case STATE_IDLE: /// unconditionally update the value
case STATE_DISABLED: /// nothing yet received - this will be it - unconditionally update the value
case STATE_DISABLED1: /// nothing yet received - this will be it - unconditionally update the value
break;
case STATE_REQUESTCONF:
if (frame < this.frame) return false; /// too early data - we are waiting for a later frame
/// see if any of the related native camera parameters did change
modif=false;
for (key in this.relatedNative) {
if (this.relatedNative[key] != AllNatPars[key]) {
modif=true;
break;
}
}
if (!modif) {
this.state=STATE_IDLE;
return false; ///none of the related native parameters did change
}
break;
default: /// do nothing
return false;
}
this.frame=frame; /// is it needed? - just in case
for (key in this.relatedNative) { /// is it needed? - just in case
this.relatedNative[key]= AllNatPars[key];
}
if (this.sValue!=val) {
this.sValue=""+val;
switch (this.varType) {
case "i": this.parValue=parseInt (this.sValue); break;
case "f": this.parValue=parseFloat(this.sValue); break;
default: this.parValue=this.sValue;
}
if (isBad(this.parValue)) {
alert("val=>"+val+"< this.parValue="+this.parValue);
}
this.newVal=true;
gRequests.scheduleAction(this.act,frame);
}
this.state=(this.state==STATE_DISABLED)?STATE_DISABLED1:STATE_IDLE;
return true;
}
/*! @brief is called when parameters are received first time from the camera, may perform some initialization now
*
*/
function parametersInitialized() {
if (gPRoot["comp_run"].getValue() != 'run') pressedCircbufNav(0) ; /// load image from the buffer?
}
/// =================================
function checkBadUrl(url,f) {
if (url.indexOf('NaN')>=0) alert_once ("Error: NaN in URL in "+f+"() - ("+url+")");
if (url.indexOf('undefined')>=0) alert_once ("Error: \"undefined\" in URL in "+f+"() - ("+url+")");
if (url=="") alert_once ("Error: empty URL in "+f+"()");
}
function dbgp(mask,txt) {
if (document.debug & mask) document.title +=txt;
}
function dbg(mask,txt) {
if (document.debug & mask) document.title =txt;
}
function alert_once(t) {
if (!gNoMoreAlerts) {
alert (t);
gNoMoreAlerts=true;
}
}
function isBad (val) {return ((typeof(val)=="undefined") || ((typeof(val)=="number") && isNaN(val)));}
/*
*! -----------------------------------------------------------------------------**
*! FILE NAME : camvc_circbuf.js
*! DESCRIPTION: Retrieves and manipulates circbuf and Exif metadata
*!
*! Copyright (C) 2008 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvc_circbuf.js,v $
*! Revision 1.6 2009/02/19 22:36:45 elphel
*! don't show GPS lat/long/alt if 0.0
*!
*! Revision 1.5 2008/12/11 06:39:11 elphel
*! reduced number of unneeded requests, corrected start when the compressor is stopped
*!
*! Revision 1.4 2008/12/10 07:25:12 elphel
*! fixing bugs that prevented this page work with Konqueror
*!
*! Revision 1.3 2008/12/09 23:35:38 elphel
*! Fixed handling Exif image description
*!
*! Revision 1.2 2008/12/05 08:10:19 elphel
*! Fixed work (at least seems so) circbuf+Exif operation
*!
*! Revision 1.1 2008/12/05 03:30:26 elphel
*! Added camvc_circbuf.js to support circbuf/Exif , restoring functionality available in 7.1
*!
*!
*/
///Set circbuf/Exif related variables when comressor is started/stopped
function circbufRun(run) {
// alert("circbufRun("+run+")");
if (run) {
gRequests.pointersAreCurrent=false;
gRequests.pointersAreNeeded= false;
gRequests.circbuf_frame_number=0;
gRequests.ExifPage=0;
gRequests.circbuf_fp="";
gRequests.ExifNeeded=false;
gRequests.ExifCircbufImgNeeded=false;
} else {
gRequests.pointersAreNeeded= true;
}
}
function pressedCircbufSingle(id) {
// document.title="pressedCircbufSingle(), id="+id;
gRequests.pointersAreCurrent=false;
gRequests.pointersAreNeeded= true;
gRequests.circbuf_frame_number=0;
gPRoot["comp_run"].setValue("single"); /// will start refresh
/// gInterface.onCompSensRun();
// startRefresh();
}
function pressedCircbufNav(delta) {
//document.title+="pressedCircbufNav("+delta+")";
// document.title="pressedCircbufNav(), delta="+delta;
if (!gRequests.pointersAreCurrent) {
gRequests.pointersAreNeeded= true;
gRequests.circbufNavigationPendingId=delta; /// was id???
startRefresh(); // TODO:it is better to store the navigation command and re-issue it after pointers are updated - DONE?
} else {
gRequests.circbufNavigationPendingId="";
// actually do the navigation
showCircbufFrame((gRequests.circbuf_frame_number?gRequests.circbuf_frame_number:gRequests.circbuf_count)+delta); // will take care of out of range
}
// showCircbufFrame(gRequests.circbuf_frame_number+delta); // will take care of out of range
// startRefresh();
}
function pressedCircbufRun(id) {
// document.title="pressedCircbufRun(), id="+id;
toggleCompressorRun();
}
function updateCircbufControls() {
if (gPRoot["comp_run"].getValue() == 'run') {
setBuTtonState("btnCircbufPrevFirst",2);
setBuTtonState("btnCircbufNextLast",2);
setBuTtonState("btnCircbufRun",1);
setBuTtonState("btnCircbufSingle",2);
} else {
setBuTtonState("btnCircbufPrevFirst",0);
setBuTtonState("btnCircbufNextLast",0);
setBuTtonState("btnCircbufRun",0);
setBuTtonState("btnCircbufSingle",0);
}
}
function getCircbuf(xmlNodes) {
// alert (xmlNodes.toSource()+" xmlNodes.length="+xmlNodes.length);
var circbuf=Array(xmlNodes.length);
var i,frame_node,fp,ep;
for (i=0;i<xmlNodes.length;i++) {
circbuf[i]={fp:parseInt(xmlNodes[i].getElementsByTagName('circbuf_pointer')[0].firstChild.nodeValue),
ep:parseInt(xmlNodes[i].getElementsByTagName('exif_pointer')[0].firstChild.nodeValue)};
}
document.getElementById("idCircbufNumber_TX").value=xmlNodes.length;
document.getElementById("idCircbufFrameNo_TX").value=xmlNodes.length; /// point to the last frame available
//document.title+="###";
// if (gRequests.circbufNavigationPendingId!="") pressedCircbufNav(gRequests.circbufNavigationPendingId);
// showCircbufFrame(xmlNodes.length);
return circbuf;
}
function showCircbufFrame(frame_num) {
//document.title+="showCircbufFrame("+frame_num+":"+gRequests.pointersAreCurrent+") ";
//alert("showCircbufFrame("+frame_num+":"+gRequests.pointersAreCurrent+") ");
if (!gRequests.pointersAreCurrent) {
gRequests.circbuf_frame_number=0;
return;
}
if (!(frame_num<=gRequests.circbuf_count)) frame_num = gRequests.circbuf_count; // to catch NaN
else if (frame_num < 1) frame_num = 1;
gRequests.circbuf_frame_number=frame_num;
document.getElementById("idCircbufFrameNo_TX").value=gRequests.circbuf_frame_number;
gRequests.ExifPage= gRequests.circbuf[gRequests.circbuf_frame_number-1].ep;
gRequests.circbuf_fp=gRequests.circbuf[gRequests.circbuf_frame_number-1].fp+"/";
gRequests.ExifNeeded=true;
gRequests.ExifCircbufImgNeeded=true;
startRefresh();
}
function parseExif(xml) {
var v;
var needsRedraw=false;
if (typeof(xml.getElementsByTagName('ImageDescription' )[0])=='undefined') {
if (document.getElementById('idImageDescription_ALL').style.display !='none') needsRedraw=true;;
document.getElementById('idImageDescription_ALL').style.display ='none';
} else {
if (document.getElementById('idImageDescription_ALL').style.display =='none') needsRedraw=true;;
document.getElementById('idImageDescription_ALL').style.display ='';
v= getIfDefinedFCNV(xml.getElementsByTagName('ImageDescription' )[0]);
if (v == "") document.getElementById("idImageDescription").innerHTML="--no description--";
else document.getElementById("idImageDescription").innerHTML=v;
}
v= getIfDefinedFCNV(xml.getElementsByTagName('DateTimeOriginal' )[0]);
if (v == "") {
if (document.getElementById('idTimestamp_ALL').style.display !='none') needsRedraw=true;;
document.getElementById("idTimestamp_ALL").style.display ="none";
} else {
if (document.getElementById('idTimestamp_ALL').style.display =='none') needsRedraw=true;;
document.getElementById("idTimestamp_ALL").style.display ="";
document.getElementById("idTimestamp").innerHTML=v;
}
v= getIfDefinedFCNV(xml.getElementsByTagName('FrameNumber' )[0]);
if (v == "") {
if (document.getElementById('idExifFrameNumber_ALL').style.display !='none') needsRedraw=true;;
document.getElementById("idExifFrameNumber_ALL").style.display ="none";
} else {
if (document.getElementById('idExifFrameNumber_ALL').style.display =='none') needsRedraw=true;;
document.getElementById("idExifFrameNumber_ALL").style.display ="";
document.getElementById("idExifFrameNumber").innerHTML=parseInt(v)+" ("+(parseInt(v) & 7)+")";
}
v= getIfDefinedFCNV(xml.getElementsByTagName('ExposureTime' )[0]);
if (v == "") {
if (document.getElementById('idExifExposure_ALL').style.display !='none') needsRedraw=true;;
document.getElementById("idExifExposure_ALL").style.display ="none";
} else {
if (document.getElementById('idExifExposure_ALL').style.display =='none') needsRedraw=true;;
document.getElementById("idExifExposure_ALL").style.display ="";
document.getElementById("idExifExposure").innerHTML=parseFloat(v);
}
v= getIfDefined0FCNV(xml.getElementsByTagName('GPSLatitude' ));
v1= getIfDefined0FCNV(xml.getElementsByTagName('GPSLongitude' ));
if ((v == "") || (v1 == "") || (v=="nan") || (v1=="nan") || ((v==0) && (v1==0))) {
if (document.getElementById('idGPSLatLong_ALL').style.display !='none') needsRedraw=true;;
document.getElementById("idGPSLatLong_ALL").style.display ="none";
v='nan';
} else {
if (document.getElementById('idGPSLatLong_ALL').style.display =='none') needsRedraw=true;;
document.getElementById("idGPSLatLong_ALL").style.display ="";
document.getElementById("idGPSLatLong").innerHTML=
"<a href='http://maps.google.com/maps?q="+v+","+v1+"' target='_blank'>"+v+","+v1+"</a>";
}
if (v !='nan') {
v= getIfDefined0FCNV(xml.getElementsByTagName('GPSAltitude' ));
v1= getIfDefined0FCNV(xml.getElementsByTagName('GPSMeasureMode' ));
}
if ((v == "") || (v1 == "" || (v=="nan") || (v1=="nan"))) {
if (document.getElementById('idGPSAltitudeMode_ALL').style.display !='none') needsRedraw=true;;
document.getElementById("idGPSAltitudeMode_ALL").style.display ="none";
} else {
if (document.getElementById('idGPSAltitudeMode_ALL').style.display =='none') needsRedraw=true;;
document.getElementById("idGPSAltitudeMode_ALL").style.display ="";
document.getElementById("idGPSAltitude").innerHTML=v+"m";
document.getElementById("idGPSMode").innerHTML=v1+"d";
}
v= getIfDefined0FCNV(xml.getElementsByTagName('GPSDateTime' ));
//alert("{"+document.getElementById('idGPSTime_ALL').style.display+"}");
if (v == "") {
if (document.getElementById('idGPSTime_ALL').style.display !='none') needsRedraw=true;;
document.getElementById("idGPSTime_ALL").style.display ="none";
} else {
if (document.getElementById('idGPSTime_ALL').style.display =='none') needsRedraw=true;;
document.getElementById("idGPSTime_ALL").style.display ="";
document.getElementById("idGPSTime").innerHTML=v;
}
v= getIfDefined0FCNV(xml.getElementsByTagName('CompassDirection' ));
if (v == "") {
if (document.getElementById('idCompassDirection_ALL').style.display !='none') needsRedraw=true;;
document.getElementById("idCompassDirection_ALL").style.display ="none";
} else {
if (document.getElementById('idCompassDirection_ALL').style.display =='none') needsRedraw=true;;
document.getElementById("idCompassDirection_ALL").style.display ="";
document.getElementById("idCompassDirection").innerHTML=v+"&deg; magnetic";
}
v= getIfDefined0FCNV(xml.getElementsByTagName('CompassPitch' ));
v1= getIfDefined0FCNV(xml.getElementsByTagName('CompassRoll' ));
if ((v == "") || (v1 == "")) {
if (document.getElementById('idCompassPitchRoll_ALL').style.display !='none') needsRedraw=true;;
document.getElementById("idCompassPitchRoll_ALL").style.display ="none";
} else {
if (document.getElementById('idCompassPitchRoll_ALL').style.display =='none') needsRedraw=true;;
document.getElementById("idCompassPitchRoll_ALL").style.display ="";
document.getElementById("idCompassPitch").innerHTML=v+"&deg";
document.getElementById("idCompassRoll").innerHTML=v1+"&deg";
}
if (needsRedraw) showWindow();
//NOTE: goes on to have circbuf in xml - should stop!
/*
if (!document.pointersAreCurrent) {
if (getIfDefinedFCNV(xml.getElementsByTagName('circbuf_count' )[0]) != "" ) getCircbuf();
}
*/
}
function ExifModifyDescription() {
var default_string=document.getElementById("idImageDescription").innerHTML;
// i=document.getElementById(id).value.indexOf("x");
if (default_string.indexOf ('no description')>=0) default_string="";
var newDescription=window.prompt("Image description",default_string);
if (newDescription!=null) {
gRequests.newDescription=escape(newDescription);
startRefresh();
}
}
/*
** -----------------------------------------------------------------------------**
** camvc_configs.js
**
** Copyright 2006 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
** camvc_configs.js is free software; you can redistribute it and/or modify it under
** the terms of the GNU General Public License as published by the Free Software
** Foundation; either version 2 of the License, or (at your option) any later version.
**
** camvc_configs.js is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with camvc_configs.js; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
** -----------------------------------------------------------------------------**
*/
/*
*! -----------------------------------------------------------------------------**
*! camvc_configs.js
*!
*! Copyright (C) 2006-2007 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvc_configs.js,v $
*! Revision 1.3 2008/12/09 19:25:17 elphel
*! After disabling default actions onmousedown - enabled all input text fields: onmousedown="this.select()" (otherwise they did not get focus when clicking them)
*!
*! Revision 1.2 2008/12/09 07:51:52 elphel
*! Partial support of ccam.ftp added alerts on non-yet-ported control tabs. Temporary launches autocampars to save selected parameters fro next autostart
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.2 2008/11/10 19:55:51 elphel
*! 8.0.alpha15 - first camvc working with 8.0 (just basic features - no autoexposure, white balance, ...), but it is now really possible (again after it was broken for quite a while) to move sliders and navigator windows without fighting with the camera that tried to move them back
*!
*! Revision 1.3 2008/01/28 18:05:24 spectr_rain
*! fix URL to save image settings for the streamer
*!
*! Revision 1.2 2008/01/28 17:10:23 spectr_rain
*! autostart of streamer if selected
*!
*! Revision 1.1.1.1 2007/09/19 04:51:17 elphel
*! This is a fresh tree based on elphel353-2.10
*!
*! Revision 1.2 2007/09/19 04:51:17 elphel
*! Upgraded license (header)
*!
*!
*/
configs_sync = -3;
configs_idle = -2;
configs_start = -1;
configs_rwNone = 0;
configs_rwNeedsReading = 1;
configs_rwReadOK = 2;
configs_rwReadError = 3;
configs_rwReadTimeout = 4;
configs_rwNeedsWriting = 5;
configs_rwWriteOK = 6;
configs_rwWriteError = 7;
configs_rwWriteTimeout = 8;
var configXML_req;
document.configNeedsSync=false;
/*
document.configs={
en:0, // enabled,
line:-2, // line number being processed (-1 - start, -2 - finished, idle)
completed:1,
timeout:3000,
colorGood: "#00dd00",
colorModified:"#0000dd",
colorBad: "#dd0000",
colorTimeout: "#dddd00",
timeOutTimerID: null,
baseUrl:"/editconf.cgi?",
url:"",
onDone:null,
buttonID:"",// button pressed (will be released when done)
wasCursor:""
};
*/
function initAllConfigs() {
// initConfigRequests();
document.configs.onDone = null;
var s = "";
var i, j;
var bid;
var onUsCh;
var cl, t;
for (i = 0; i < document.configsData.length; i++) {
if (typeof(document.configsData[i].quote) == "undefined")
document.configsData[i].quote = "";
if (typeof(document.configsData[i].txWidth) == "undefined")
document.configsData[i].txWidth = 8;
if (typeof(document.configsData[i].onUpdate) == "undefined")
document.configsData[i].onUpdate = null;
if (typeof(document.configsData[i].onUserChange) == "undefined")
document.configsData[i].onUserChange = null;
if (typeof(document.configsData[i].onWriteConfig) == "undefined")
document.configsData[i].onWriteConfig = null;
if (typeof(document.configsData[i].enUpd) == "undefined")
document.configsData[i].enUpd = 1;
if (typeof(document.configsData[i].val) == "undefined")
document.configsData[i].val = "";
if (typeof(document.configsData[i].rwState) == "undefined")
document.configsData[i].rwState = 0;
if (typeof(document.configsData[i].stl) == "undefined")
document.configsData[i].stl = "";
if (typeof(document.configsData[i].disabled) == "undefined")
document.configsData[i].disabled = 0;
document.configsData[i].valio = "";
with(document.configsData[i]) {
// add header/buttons if they do not yet exist ("_head and _LB" section should exist already
if (document.getElementById(divId + '_head') && (!document.getElementById(divId + '_readThis'))) {
s = "";
if (document.getElementById(divId + '_autofill')) {
s += '<div id="' + divId + '_auto" style="float:right;width:25;height:25;"></div>\n';
document.buTtons[document.buTtons.length] = {
id: divId + "_auto", n: 48, t: "b", dm: "", aop:"pressedConfigsRw(id);"};
}
s += '<div id="' + divId + '_saveAll" style="float:right;width:25;height:25;"></div>\n';
s += '<div id="' + divId + '_saveThis" style="float:right;width:25;height:25;"></div>\n';
s += '<div id="' + divId + '_readAll" style="float:right;width:25;height:25;"></div>\n';
s += '<div id="' + divId + '_readThis" style="float:right;width:25;height:25;"></div>\n';
document.getElementById(divId + '_head').innerHTML += s;
document.buTtons[document.buTtons.length] = {
id: divId + "_saveAll", n: 45, t: "b", dm: "", aop:"pressedConfigsRw(id);"};
document.buTtons[document.buTtons.length] = {
id: divId + "_saveThis", n: 44, t: "b", dm: "", aop:"pressedConfigsRw(id);"};
document.buTtons[document.buTtons.length] = {
id: divId + "_readAll", n: 47, t: "b", dm: "", aop:"pressedConfigsRw(id);"};
document.buTtons[document.buTtons.length] = {
id: divId + "_readThis", n: 46, t: "b", dm: "", aop:"pressedConfigsRw(id);"};
} // needed header
onUsCh = onUserChange ? "'" + onUserChange + "'" : "null";
cl = (((typeof(document.configsData[i].stl) != "undefined")) && (stl != "")) ? (' style="' + stl + '"') : "";
t = (((typeof(document.configsData[i].password) != "undefined")) && document.configsData[i].password) ? "password" : "text";
var dsbl = disabled ? " disabled " : ""; // select between "disabled" and "readonly"
if (frmt == 0) { // custom formatting add extra filed
s = custom;
} else {
s = '<div id="' + id + 'All" class="settings_item"><span id="' + id + '_LB" style="float:left;"></span>';
if (frmt == 1) { //text field
s += ' <span style="float:right;"><input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX" ' + dsbl;
if (txWidth > 0)
s += 'size="' + txWidth + '" ';
s += 'onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/></span>\n';
} else if (frmt == 2) { //checkbox
bid = id + "_CB";
s += ' <div id="' + bid + '" style="float:right;width:25;height:25;"></div><input type="hidden" id="' + id + '_TX"/>\n';
// create button in document.buTtons array
document.buTtons[document.buTtons.length] = {
id: bid, n: txWidth, t: "T2", dm: "", aop:"inputInChange(" + i + "," + onUsCh + ");"};
//alert (document.buTtons[document.buTtons.length-1].aop);
} else if (frmt == 3) { // ipv4
s += '<div id="' + id + '_ipv4" style="float:right;">';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX1" ' + dsbl + 'size="3" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>.';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX2" ' + dsbl + 'size="3" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>.';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX3" ' + dsbl + 'size="3" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>.';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX4" ' + dsbl + 'size="3" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>';
s += '</div>';
s += ' <input type="hidden" id="' + id + '_TX"/>\n';
} else if (frmt == 5) { //Select
s += ' <span style="float:right;"><select id="' + id + '_TX" ' + dsbl;
if (txWidth > 0)
s += 'size="' + txWidth + '" ';
s += 'onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '>\n';
for (j = 0; j < sel.length; j++)
s += '<option value="' + sel[j] + '">' + sel[j] + '</option>\n';
s += '</select></span>\n';
} else if (frmt == 6) { // MAC format (xx:xx:xx:xx:xx:xx)
s += '<div id="' + id + '_mac" style="float:right;">';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX1" ' + dsbl + 'size="2" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>:';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX2" ' + dsbl + 'size="2" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>:';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX3" ' + dsbl + 'size="2" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>:';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX4" ' + dsbl + 'size="2" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>:';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX5" ' + dsbl + 'size="2" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>:';
s += '<input onmousedown="this.select()" type="' + t + '" id="' + id + '_TX6" ' + dsbl + 'size="2" onChange="inputInChange(' + i + ',' + onUsCh + ')"' + cl + '/>';
s += '</div>';
s += ' <input type="hidden" id="' + id + '_TX"/>\n';
} else { // error
alert("Unknown format=" + frmt);
}
s += '</div>\n';
}
document.getElementById(divId).innerHTML += s;
}
}
}
function configs_cameraTimer(t) {
document.configs.timeOutTimerID = self.setTimeout("configs_cameraTimeout()", t);
document.configs.completed = 1;
}
function configs_cameraTimeout() {
document.configs.completed = 0;
configs_mainLoop();
}
function startConfigs() {
if (document.configs.line != configs_idle) {
alert("configs update is already in progress");
return; // will not start next update until the current is over
}
document.configs.line = configs_start;
completed = 1;
configs_mainLoop();
}
function configs_mainLoop() {
var t = new Date();
var v, i, j;
with(document.configs) {
// stop timeout timer if running
if (timeOutTimerID) {
clearTimeout(timeOutTimerID);
timeOutTimerID = null;
}
if (line == configs_idle) {
return; // nothing to be done, exiting
}
if (line >= 0) { // process the current line with the data received (will skip if (line==configs_sync) {
if (document.configsData[line].rwState == configs_rwNeedsReading) {
if (!completed) {
document.configsData[line].rwState = configs_rwReadTimeout;
} else {
// try to parse XML data
if (!configXML_req.responseXML.getElementsByTagName('value')[0]) {
document.configsData[line].val = ""; // for now - empty on any other errors (maybe really check on error type?
document.configsData[line].rwState = configs_rwReadError;
document.getElementById(document.configsData[line].id + "_TX").value = document.configsData[line].val;
} else {
document.configsData[line].val = configXML_req.responseXML.getElementsByTagName('value')[0].firstChild.nodeValue;
document.configsData[line].rwState = configs_rwReadOK;
// unquote
if (document.configsData[line].val.substr(0, 1) == "\"")
document.configsData[line].quote = "\""; // set from config
if (document.configsData[line].val.substr(0, 1) == "'")
document.configsData[line].quote = "'"; // set from config
if ((typeof(document.configsData[line].quote) != "undefined") && document.configsData[line].quote) {
// if (document.configsData[line].val.substr(0,1)=="\"") {
// document.configsData[line].quote=1; // set from config
while ((document.configsData[line].val.length > 0) && (document.configsData[line].val.substr(0, 1) == document.configsData[line].quote))
document.configsData[line].val = document.configsData[line].val.substr(1);
while ((document.configsData[line].val.length > 0)
&& (document.configsData[line].val.substr(document.configsData[line].val.length - 1) == document.configsData[line].quote))
document.configsData[line].val = document.configsData[line].val.substr(0, document.configsData[line].val.length - 1);
}
document.getElementById(document.configsData[line].id + "_TX").value = document.configsData[line].val;
// substitute .yes and .no choices with "1" or "0"
if (document.configsData[line].no) {
if (document.configsData[line].val == document.configsData[line].no)
document.getElementById(document.configsData[line].id + "_TX").value = "0";
else
document.getElementById(document.configsData[line].id + "_TX").value = "1";
}
if (document.configsData[line].frmt == 3) { //ip - split into 4 groups
v = document.configsData[line].val;
for (i = 1; (v != "") && (i <= 4) && ((j = v.indexOf(".")) > 0); i++) {
document.getElementById(document.configsData[line].id + "_TX" + i).value = v.substr(0, j);
v = v.substr(j + 1);
}
if (v)
document.getElementById(document.configsData[line].id + "_TX" + i).value = v;
}
if (document.configsData[line].frmt == 5) { // select
//document.title+=document.configsData[line].val;
for (i = 0; i < document.getElementById(document.configsData[line].id + "_TX").options.length; i++) {
if (document.getElementById(document.configsData[line].id + "_TX").options[i].value == document.configsData[line].val) {
document.getElementById(document.configsData[line].id + "_TX").options[i].selected = true;
// document.getElementById(document.configsData[line].id+"_TX").style.color=document.configs.colorGood;
} else {
document.getElementById(document.configsData[line].id + "_TX").options[i].selected = false;
// document.getElementById(document.configsData[line].id+"_TX").style.color=document.configs.colorModified;
}
//document.title+=" "+document.getElementById(document.configsData[line].id+"_TX").options[i].value+"/"+document.getElementById(document.configsData[line].id+"_TX").options[i].selected;
}
// alert(document.title);
}
if (document.configsData[line].frmt == 6) { //mac - split into 6 groups
v = document.configsData[line].val;
for (i = 1; (v != "") && (i <= 6) && ((j = v.indexOf(":")) > 0); i++) { // use configured (as an extra parameter in the table) separator, not just ":"?
document.getElementById(document.configsData[line].id + "_TX" + i).value = v.substr(0, j);
v = v.substr(j + 1);
}
if (v)
document.getElementById(document.configsData[line].id + "_TX" + i).value = v;
}
// show checkbox state according to data read
if (document.configsData[line].frmt == 2) { //checkbox, not text field
setBuTtonState(document.configsData[line].id + "_CB", parseInt(document.getElementById(document.configsData[line].id + "_TX").value) ? 1 : 0);
}
// perform exteranal action if needed
if (document.configsData[line].onUpdate) {
var tid = document.configsData[line].id + "_TX";
eval(document.configsData[line].onUpdate); // before converting to checkbox
}
}
// document.getElementById("input_"+line).value=document.configsData[line].val;
}
document.configsData[line].valio = document.configsData[line].val;
} else if (document.configsData[line].rwState == configs_rwNeedsWriting) {
if (!completed) {
document.configsData[line].rwState = configs_rwWriteTimeout;
} else {
// try to parse XML data
if ((!configXML_req.responseXML.getElementsByTagName('error')[0])
|| (parseInt(configXML_req.responseXML.getElementsByTagName('error')[0].firstChild.nodeValue) != 0)) {
document.configsData[line].rwState = configs_rwWriteError;
} else {
document.configsData[line].rwState = configs_rwWriteOK;
document.configsData[line].valio = document.configsData[line].val; // valio has value last read/written to the camera
// perform accosiated action after the config data is written to the camera
if (document.configsData[line].onWriteConfig && (typeof(document.configsData[line].onWriteConfig) != "undefined")) {
var tid = document.configsData[line].id + "_TX";
eval(document.configsData[line].onWriteConfig); // before converting to checkbox
}
}
}
} else
alert_once("error #1 in configs_mainLoop(), document.configsData[" + line + "].rwState=" + document.configsData[line].rwState);
}
if (line==configs_sync) {
// alert ("synced");
document.configNeedsSync=false;
line = document.configsData.length;
} else {
if (line < 0) {
line = 0;
} else line++;
while ((line < document.configsData.length) && (((document.configsData[line].rwState != configs_rwNeedsReading) && (document.configsData[line].rwState != configs_rwNeedsWriting))
|| !document.configsData[line].enUpd)) {
line++;
}
}
if (line >= document.configsData.length) {
if (document.configNeedsSync) {
url = selfUrl + "sync" + "&_time=" + t.getTime();
// alert (url);
line=configs_sync;
startConfigsXML();
return;
}
line = configs_idle;
if (onDone)
onDone();
return; //normal finish
} else if (document.configsData[line].rwState == configs_rwNeedsReading) {
// create read url
if (document.configsData[line].file=="internal") {
url = selfUrl + "key=" + document.configsData[line].key + "&_time=" + t.getTime();
} else {
url = baseUrl + "file=" + document.configsData[line].file + "&key=" + document.configsData[line].key + "&_time=" + t.getTime();
}
startConfigsXML();
return;
} else if (document.configsData[line].rwState == configs_rwNeedsWriting) {
// create write url
if (document.configsData[line].file=="internal") {
url = selfUrl + "key=" + document.configsData[line].key;
} else {
url = baseUrl + "file=" + document.configsData[line].file + "&key=" + document.configsData[line].key;
document.configNeedsSync=true;
}
// "&value="+(document.configsData[line].quote?"\"":"")+document.configsData[line].val+(document.configsData[line].quote?"\"":"")+
if(document.configsData[line].quote || document.configsData[line].val) {
url += "&value=" + document.configsData[line].quote + document.configsData[line].val + (document.configsData[line].quote ? "\"" : "");
url += (document.configsData[line].eq ? "&eq=1" : "");
} else { // now quotes, empty string - remove the key copmpletely
url += "&value=%23"; // %23 - same as #, but # in url has a special meaning
}
url += "&_time=" + t.getTime();
startConfigsXML();
// moved where confiramtion is received, so external program can rely on the updated data in the config file
// if (document.configsData[line].onWriteConfig && (typeof(document.configsData[line].onWriteConfig)!="undefined")) {
// var tid=document.configsData[line].id+"_TX";
// eval (document.configsData[line].onWriteConfig); // before converting to checkbox
// }
return;
} else
alert_once("error #2 in configs_mainLoop(), document.configsData[" + line + "].rwState=" + document.configsData[line].rwState);
} // with (document.configs)
}
function startConfigsXML() {
configs_cameraTimer(document.configs.timeout);
checkBadUrl(document.configs.url, "startConfigsXML");
if (window.XMLHttpRequest) {
configXML_req = new XMLHttpRequest();
configXML_req.onreadystatechange = receivedConfigsXML;
configXML_req.open("GET", document.configs.url, true);
configXML_req.send(null);
// branch for IE/Windows ActiveX version
}
}
function receivedConfigsXML() {
// only if req shows "loaded"
if (typeof(configXML_req) == "undefined")
return; //trying to fight "uncaught exceptions" (happens when camera is setting it is date)
if (configXML_req.readyState == 4) {
// only if "OK"
if (((configXML_req.status >= 200) && (configXML_req.status < 300)) || (configXML_req.status ==304) ||
((typeof(configXML_req.status) =='undefined' ) && ((navigator.userAgent.indexOf("Safari")>=0) || (navigator.userAgent.indexOf("Konqueror")>=0))))
{ //
configs_mainLoop(); // **** back to main loop ****
} else {
alert_once("There was a problem retrieving the XML data:\n" + configXML_req.statusText);
}
}
}
//-----------------------------
function configInputsChanged() {
var i;
for (i = 0; i < document.configsData.length; i++)
inputInChange(i, null);
}
function inputInChange(i, act) {
// var i=parseInt(id.substr(6));
var n, v, s, v0, indx, vi, j;
var id = document.configsData[i].id + "_TX";
if (document.configsData[i].disabled)
return;
if (document.configsData[i].frmt == 2) { //checkbox, not text field
// setBuTtonState(document.configsData[line].id+"_CB", parseInt(document.configsData[line].val)?1:0);
document.getElementById(id).value = getBuTton(document.configsData[i].id + "_CB").s ? "1" : "0";
if (document.configsData[i].yes) { // "no" may be empty, while "yes" is not. In that case the key/value pair may be removed completely
document.getElementById(id).value = getBuTton(document.configsData[i].id + "_CB").s ? document.configsData[i].yes : document.configsData[i].no;
}
} else if (document.configsData[i].frmt == 3) { // ipv4
s = "";
v0 = document.configsData[i].valio;
for (n = 1; n <= 4; n++) {
indx = v0.indexOf(".");
if (indx < 0)
indx = v0.length;
vi = parseInt(v0.substr(0, indx));
v = parseInt(document.getElementById(id + n).value);
if (!((v >= 0) && (v < 256)))
v = vi;
document.getElementById(id + n).value = v;
s += v;
if (n < 4)
s += ".";
if (v != vi)
document.getElementById(id + n).style.color = document.configs.colorModified;
else
document.getElementById(id + n).style.color = document.configs.colorGood;
v0 = v0.substr(indx + 1);
}
document.getElementById(id).value = s;
} else if (document.configsData[i].frmt == 6) { // mac
s = "";
v0 = document.configsData[i].valio;
for (n = 1; n <= 6; n++) {
indx = v0.indexOf(":");
if (indx < 0)
indx = v0.length;
// Make hex verification later if needed
// vi=parseInt(v0.substr(0,indx));
// v=parseInt(document.getElementById(id+n).value);
// if (!((v>=0) && (v<256))) v=vi;
vi = v0.substr(0, indx);
v = document.getElementById(id + n).value;
if (v.length == 2)
v = vi;
document.getElementById(id + n).value = v;
s += v;
if (n < 6)
s += ":";
if (v != vi)
document.getElementById(id + n).style.color = document.configs.colorModified;
else
document.getElementById(id + n).style.color = document.configs.colorGood;
v0 = v0.substr(indx + 1);
}
document.getElementById(id).value = s;
}
if (act)
eval(act);
if (document.configsData[i].frmt == 5) {
for (j = 0; j < document.getElementById(id).options.length; j++) {
if (document.getElementById(id).options[j].selected) {
document.configsData[i].val = document.getElementById(id).options[j].value;
}
}
} else {
document.configsData[i].val = document.getElementById(id).value;
}
//document.title= document.configsData[i].val+"/"+document.configsData[i].valio;
if (document.configsData[i].val != document.configsData[i].valio) {
// if (document.configsData[i].frmt!=5)
document.getElementById(document.configsData[i].id + "_TX").style.color = document.configs.colorModified;
document.configsData[i].rwState = configs_rwNeedsWriting;
} else { // restored to an old (synchronized with camera) value
// if (document.configsData[i].frmt!=5)
document.getElementById(document.configsData[i].id + "_TX").style.color = document.configs.colorGood;
document.configsData[i].rwState = configs_rwNone; //set to the old read/written value
}
}
function set_initstring(s) {
// u = "/editconf.cgi?file=/etc/streamers.conf"
// u = "/strconf.cgi?out=/etc/image.conf&in=/var/state/image.conf"
u = "/imconf_save.php"
// u += s;
if (window.XMLHttpRequest) {
configXML_req = new XMLHttpRequest();
// configXML_req.onreadystatechange = receivedConfigsXML;
configXML_req.open("GET", u, true);
configXML_req.send(null);
}
}
function update_initstrings() {
var s = "&init_1=\'"+document.init_1+"\'";
s += "&init_2=\'"+document.init_2+"\'";
set_initstring(s);
/*
if(_init_1 != document.init_1) {
_init_1 = document.init_1;
var s = "&key=init_1&value=\'"+_init_1+"\'"
set_initstring(s);
// ...
}
if(_init_2 != document.init_2) {
_init_2 = document.init_2;
var s = "&key=init_2&value=\'"+_init_2+"\'"
set_initstring(s);
// ...
}
alert("bla-bla!");
*/
}
function pressedConfigsRw(id) {
var i, j;
if (document.configs.buttonID != "") {
return; //button already will get to state 2
}
if ((id.indexOf("_save") > 0) && !document.shiftKey) {
alert(document.getElementById("h_idShiftWarn").innerHTML); // alert causes error here in Mozilla FF
if (document.buTton)
document.buTton.s = 0;
return;
}
document.configs.buttonID = id;
if (document.buTton)
document.buTton.s = 1; // a hack to prevent button go to released state when it is released
document.configs.wasCursor = document.body.style.cursor;
document.body.style.cursor = "wait";
if ((j = id.indexOf("_readThis")) > 0) {
for (i = 0; i < document.configsData.length; i++) {
if (id.substr(0, j) == document.configsData[i].divId) {
document.configsData[i].rwState = configs_rwNeedsReading;
document.configsData[i].enUpd = 1;
} else {
document.configsData[i].enUpd = 0;
}
}
document.configs.onDone = readConfigsDone;
startConfigs();
} else if ((j = id.indexOf("_readAll")) > 0) {
for (i = 0; i < document.configsData.length; i++) {
document.configsData[i].rwState = configs_rwNeedsReading;
document.configsData[i].enUpd = 1;
}
document.configs.onDone = readConfigsDone;
startConfigs();
} else if ((j = id.indexOf("_saveThis")) > 0) {
for (i = 0; i < document.configsData.length; i++) {
if (id.substr(0, j) == document.configsData[i].divId) {
document.configsData[i].enUpd = document.configsData[i].disabled ? 0 : 1;
} else {
document.configsData[i].enUpd = 0;
}
}
document.configs.onDone = writeConfigsDone;
startConfigs();
// TODO!
if(id == "idSettingsTabs_div3_saveThis") {
update_initstrings();
}
} else if ((j = id.indexOf("_saveAll")) > 0) {
for (i = 0; i < document.configsData.length; i++) {
document.configsData[i].enUpd = document.configsData[i].disabled ? 0 : 1;
}
document.configs.onDone = writeConfigsDone;
startConfigs();
update_initstrings();
} else if ((j = id.indexOf("_auto")) > 0) {
if (document.getElementById(id.substr(0, j) + "_autofill")) {
eval(document.getElementById(id.substr(0, j) + "_autofill").value);
}
// configsAutoFill(id.substr(0,j)); // argument - section name
if (document.buTton)
document.buTton.s = 0; // a hack to prevent button go to released state when it is released
setBuTtonState(document.configs.buttonID, 0);
document.configs.buttonID = "";
document.body.style.cursor = document.configs.wasCursor;
} else {
alert("unrecognized id=" + id);
if (document.buTton)
document.buTton.s = 0; // a hack to prevent button go to released state when it is released
setBuTtonState(document.configs.buttonID, 0);
document.configs.buttonID = "";
document.body.style.cursor = document.configs.wasCursor;
}
}
function writeConfigsDone() { // red - errorsm green - written, others - don not touch
var i, id, j;
for (i = 0; i < document.configsData.length; i++) {
// id=document.configsData[i].id+((document.configsData[i].frmt==3)?"_ipv4":"_TX");
id = document.configsData[i].id + "_TX";
if (document.configsData[i].frmt == 5) {
for (j = 0; j < document.getElementById(id).options.length; j++) {
if (document.getElementById(id).options[j].selected) {
document.getElementById(id).options[j].style.color = document.configs.colorGood;
} else {
document.getElementById(id).options[j].style.color = document.configs.colorModified;
}
}
document.getElementById(id).style.color = document.configs.colorGood;
} else {
for (j = 0; j < ((document.configsData[i].frmt == 3) ? 5 : 1); j++) {
if (document.configsData[i].rwState == configs_rwWriteOK) {
document.getElementById(id + (j ? j : "")).style.color = document.configs.colorGood;
} else if (document.configsData[i].rwState == configs_rwWriteError) {
document.getElementById(id + (j ? j : "")).style.color = document.configs.colorBad;
} else if (document.configsData[i].rwState == configs_rwWriteTimeout) {
document.getElementById(id + (j ? j : "")).style.color = document.configs.colorTimeout;
} else {
}
}
}
}
if (document.buTton)
document.buTton.s = 0; // a hack to prevent button go to released state when it is released
setBuTtonState(document.configs.buttonID, 0);
document.configs.buttonID = "";
document.body.style.cursor = document.configs.wasCursor;
}
function readConfigsDone() {
var i, id, j;
for (i = 0; i < document.configsData.length; i++) {
// id=document.configsData[i].id+((document.configsData[i].frmt==3)?"_ipv4":"_TX");
id = document.configsData[i].id + "_TX";
if (document.configsData[i].frmt == 5) {
for (j = 0; j < document.getElementById(id).options.length; j++) {
if (document.getElementById(id).options[j].selected) {
document.getElementById(id).options[j].style.color = document.configs.colorGood;
} else {
document.getElementById(id).options[j].style.color = document.configs.colorModified;
}
}
} else {
for (j = 0; j < ((document.configsData[i].frmt == 3) ? 5 : 1); j++) {
if (document.configsData[i].rwState == configs_rwReadOK) {
document.getElementById(id).value = document.configsData[i].val;
document.getElementById(id + (j ? j : "")).style.color = document.configs.colorGood;
} else if (document.configsData[i].rwState == configs_rwReadError) {
document.getElementById(id + (j ? j : "")).style.color = document.configs.colorBad;
} else if (document.configsData[i].rwState == configs_rwReadTimeout) {
document.getElementById(id + (j ? j : "")).style.color = document.configs.colorTimeout;
} else {
// document.getElementById(id).style.color="#000000";
}
}
}
}
if (document.buTton)
document.buTton.s = 0; // a hack to prevent button go to released state when it is released
setBuTtonState(document.configs.buttonID, 0);
document.configs.buttonID = "";
document.body.style.cursor = document.configs.wasCursor;
}
/*
*! -----------------------------------------------------------------------------**
*! camvc_dvr.js
*!
*! Copyright (C) 2006-2007 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvc_dvr.js,v $
*! Revision 1.2 2008/11/30 06:41:43 elphel
*! changed default IP back to 192.168.0.9 (temporarily was 192.168.0.7)
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.2 2008/09/28 00:28:25 elphel
*! Default IP changed to 192.168.0.9
*!
*! Revision 1.2 2007/12/04 01:15:36 spectr_rain
*! added support of RTSP
*!
*! Revision 1.1.1.1 2007/09/19 04:51:17 elphel
*! This is a fresh tree based on elphel353-2.10
*!
*! Revision 1.2 2007/09/19 04:51:17 elphel
*! Upgraded license (header)
*!
*!
*/
document.dvrScript="/caminfo.php";
document.retransmitUrl="/xmlxmt.cgi";
document.dvrButton2Press=-1; // press this button after registering at the DB
//document.dvrDefaultModes={loop:0,cont:1,server:"192.168.0.1",maxFileSize:100,maxFileDur:60};
document.dvrDefaultModes={loop:0,cont:1,server:"",maxFileSize:100,maxFileDur:60};
// if (getBuTton("idDVRLoop_CB").s) {
// } else if (getBuTton("idDVRNextPlay_CB").s){
//document.dvrwasCursor="";
var DVRVideoStateStop= 0;
var DVRVideoStateLive= 1;
var DVRVideoStateLiveP=2;
var DVRVideoStatePlay= 3;
var DVRVideoStatePlayP=4;
var DVR_state_camTry = 1;
var DVR_state_camAdd = 2;
var DVR_state_camReTry = 3;
var DVR_state_camEdit = 4;
var DVR_state_sessions = 5; //read all/last sessions
var DVR_state_record = 6;
var DVR_state_stop = 7;
//button numbers
var DVRBack=1;
var DVRPlay=2;
var DVRPause=3
var DVRStop=4;
var DVRForward=5
var DVRRecord=6;
var DVRList=7;
var DVRSettings=8;
var DVRStopRecord=9;
var DVRSearch=10;
document.DVRRetriesConfirmRecord=3; // number of retries to confirm recording start/stop
document.DVRRetriesConfirmRecordLeft=0; //
//document.serverRoot="/vcr_lamp";
document.serverRoot="/dvr";
var DVRxml_req;
var DVRDBxml_req;
document.enableForwardRetry=true; // if true and forward hit the end of records - it will try to get DB data to sse if a newer record appeared
document.videoFiles=new Array(0);
document.sessions=null;
document.DVR_state=DVR_state_camTry;
//document.DVR_fileNum={ses:-1,fil:0,pos:0};
document.DVR_fileNum={len:-1,n:-1,fil:0,pos:0};
function dvrServerIpChanged() {
document.DVR_state=DVR_state_camTry;
}
function searchDVR() {
req_DVR();
}
function req_DVR() { // arg - "", "start", "stop"
var t=new Date();
var url="http://"+document.getElementById("idDVRServer_TX").value+document.dvrScript+
"?camera="+ escape(document.getElementById("idDVRCameraID_TX").value)+
"&start="+ escape(document.getElementById("idDVRStart_TX").value)+
"&end="+ escape(document.getElementById("idDVREnd_TX").value)+
"&_time="+t.getTime();
checkBadUrl(url,"req_DVR");
//
// Cross-domain xmlHTTPRequests do not work because of the security limitations in Mozilla. We will use camera
// to re-transmit requests to the server and return the results back. It might be a waste, but xml files are supposed
// to be small ones.
// server URL should be IP, camera does not support DNS
//
url=document.retransmitUrl+"?"+escape(url);
// document.title=url;
if(window.XMLHttpRequest) {
DVRxml_req = new XMLHttpRequest();
DVRxml_req.onreadystatechange = req_DVR_rec;
DVRxml_req.open("GET", url, true);
DVRxml_req.send(null);
} else if(window.ActiveXObject) {
DVRxml_req = new ActiveXObject("Microsoft.XMLHTTP");
if(DVRxml_req) {
DVRxml_req.onreadystatechange = req_DVR_rec;
DVRxml_req.open("GET", url, true);
DVRxml_req.send();
}
}
}
function req_DVR_rec() {
if (typeof(DVRxml_req)=="undefined") return; //trying to fight "uncaught exceptions" (happens when camera is setting it's date)
if (DVRxml_req.readyState == 4) {
// only if "OK"
if (DVRxml_req.status == 200) { // if camera time was not set in advance, "uncaught exception" will be here
// ...processing statements go here...
req_DVR_rec_got(); // **** back to main loop ****
} else {
alert_once("There was a problem retrieving the XML data:\n" +
DVRxml_req.statusText);
}
}
}
//AEXML_req.responseXML.getElementsByTagName('BPERC' )[0].firstChild.nodeValue
function req_DVR_rec_got() { // parse it here
var i,l,j,s;
var n=DVRxml_req.responseXML.getElementsByTagName("clip" ).length;
var clips=new Array(n);
alert ("n="+n);
for (i=0;i<n;i++) {
clips[i]={};
l=DVRxml_req.responseXML.getElementsByTagName("clip" )[i].childNodes.length;
for (j=0;j<l;j++) {
if (DVRxml_req.responseXML.getElementsByTagName("clip" )[i].childNodes[j].nodeName !="#text") {
clips[i][DVRxml_req.responseXML.getElementsByTagName("clip" )[i].childNodes[j].nodeName]=
DVRxml_req.responseXML.getElementsByTagName("clip" )[i].childNodes[j].childNodes[0].nodeValue;
}
}
}
// alert ("i="+i+" l="+l+"\n"+s);
//alert(DVRxml_req.responseText);
s="";
for (i=0;i<n;i++) {
s+=" camera_id="+clips[i].camera_id;
s+=" file="+clips[i].file;
s+=" startTime="+clips[i].startTime;
s+=" duration="+clips[i].duration;
s+=" frames="+clips[i].frames;
s+=" width="+clips[i].width;
s+=" height="+clips[i].height;
s+="\n";
}
alert(s);
}
function setMac(){
document.MAC="";
var i,c;
for (i=0;i<document.getElementById("idConfNetMac_TX").value.length;i++) {
c=document.getElementById("idConfNetMac_TX").value.substr(i,1);
if ("0123456789ABCDEF".indexOf(c) >=0) document.MAC+=c;
}
document.getElementById("idDVRCameraID_TX").value=document.MAC;
parameresToSyncChanged();
}
function changedIP(n){ // 0 - camera ip, 1 - multi/uni- streamer IP, 2 - multi/uni port
var i=configsNumberById("idVideoDestIp")
// var multicast=(document.configsData[i].val.substr(0,3)=="232");
if (n==0) {
document.getElementById("idDVRCameraIP1_TX").value =
document.configsData[configsNumberById("idConfNetIP")].val;
} else if (n==1) {
document.getElementById("idDVRCameraIP2_TX").value = document.configsData[configsNumberById("idVideoDestIp")].val;
} else if (n==2) {
document.getElementById("idDVRCameraIP2Port_TX").value = document.configsData[configsNumberById("idVideoDestPort")].val;
}
parameresToSyncChanged()
}
// - 3 try to register camera
// - 2
function parameresToSyncChanged(){
// alert ("registering camera on server");
}
function DVRcursor(c) {
if (document.getElementById("idDVRInfo").style.cursor!=c) {
document.getElementById("idDVRInfo").style.cursor= c;
document.getElementById("idDVRButtons").style.cursor= c;
document.getElementById("idDivDVR").style.cursor= c;
}
}
/*
<span id="idInfoWidth" style="float:left;font-weight:bold; cursor:pointer;" onclick="released_btnPositioningShow(0);">0</span>
<span id="idInfoHeight" style="float:left;font-weight:bold; cursor:pointer;" onclick="released_btnPositioningShow(0);">0</span>
<span id="idSpanFPS" style="color:green; float:left;font-weight:bold; cursor:pointer;" onclick="released_btnPhotoShow(3);">00.0</span>
var DVR_state_record = 6;
var DVR_state_stop = 7;
i=document.videoFiles[document.videoFiles.length-1].s;
for (j=0;j<lastSessions.session.length;j++) {
// alert ("i="+i+" j="+j+"\n"+lastSessions.session[j].toSource());
document.sessions.session[i++]=lastSessions.session[j];
*/
/*
Always register before start and stop, make sure strat is not issued if it is running
*/
function dvrRegisterOnly() {
document.dvrButton2Press=-1;
dvrRegister();
}
/*
http://166.70.153.79/vcr_lamp/camera.php?cmd=list
http://166.70.153.79/vcr_lamp/camera.php?cmd=list&mac=aabbccddeeff
http://166.70.153.79/vcr_lamp/camera.php?cmd=add&mac=a1b2c3d4e5f6&ip1=192.168.0.1&place=Dream+House
http://166.70.153.79/vcr_lamp/session.php?cmd=list
http://166.70.153.79/vcr_lamp/session.php?cmd=list&min_start_time=1142359996
http://166.70.153.79/vcr_lamp/session.php?cmd=list&min_start_time=1142359996&max_start_time=1142359996
http://166.70.153.79/vcr_lamp/session.php?cmd=start&mac=aabbccddeeff&strm_ip=232.168.0.9&strm_port=20000&fps=1&width=512&height=384
http://166.70.153.79/vcr_lamp/session.php?cmd=stop&mac=aabbccddeeff&ses_id=3
*/
document.lastDVRurl="";
function dvrRegister() {
var t=new Date();
DVRcursor("wait");
var v;
var url="http://"+document.getElementById("idDVRServer_TX").value;
if (document.getElementById("idDVRServerPort_TX").value!="") url+=":"+document.getElementById("idDVRServerPort_TX").value;
// alert (document.getElementById("idDVRServer_TX").value.length);
if (document.getElementById("idDVRServer_TX").value=="") { // try to get IP of this computer from the camera
DVRXMLHttpRequest(document.retransmitUrl); // no parameters, get environment
return;
}
url+=document.serverRoot;
if ((document.DVR_state==DVR_state_camTry) || (document.DVR_state==DVR_state_camReTry)) {
url+="/camera.php?cmd=list";
} else if (document.DVR_state==DVR_state_camAdd) {
url+="/camera.php?cmd=add";
} else if (document.DVR_state==DVR_state_camEdit) {
url+="/camera.php?cmd=edit";
} else if (document.DVR_state==DVR_state_sessions) {
url+="/session.php?cmd=list";
} else if (document.DVR_state==DVR_state_record) {
url+="/session.php?cmd=start";
if ((document.sessions.session.length>0) && (parseInt(document.sessions.session[document.videoFiles[document.videoFiles.length-1].s].stop_stream) == 0)) {
document.DVR_state=DVR_state_sessions;
DVRcursor("");
return; // stream already is being recorded
}
} else if (document.DVR_state==DVR_state_stop) {
url+="/session.php?cmd=stop";
if ((document.sessions.session.length==0) ||(parseInt(document.sessions.session[document.videoFiles[document.videoFiles.length-1].s].stop_stream) > 0)) {
document.DVR_state=DVR_state_sessions;
DVRcursor("");
return; // stream recording is already is stopped (or never started)
}
} else {
alert("unexpected state of document.DVR_state = "+document.DVR_state);
DVRcursor("");
return;
}
// url+="?fmt=xml&mac="+escape(document.getElementById("idDVRCameraID_TX").value);
url+="&fmt=xml&mac="+escape(document.getElementById("idDVRCameraID_TX").value);
if (document.DVR_state==DVR_state_camEdit) {
if (document.getElementById("idDVRCameraIP1_TX").value!="") url+="&ip1="+escape(document.getElementById("idDVRCameraIP1_TX").value);
if (document.getElementById("idDVRLocation_TX").value!="") url+="&place="+escape(escape(document.getElementById("idDVRLocation_TX").value));
} else if ((document.DVR_state==DVR_state_sessions) && (document.videoFiles.length>0)) { // already registered - will continue
url+="&min_start_time="+document.sessions.session[document.videoFiles[document.videoFiles.length-1].s].start_stream;
} else if (document.DVR_state==DVR_state_record) {
url+="&strm_rtsp_ip=" +document.configsData[configsNumberById("idConfNetIP")].val;
url+="&strm_ip=" +document.getElementById("idDVRCameraIP2_TX").value;
url+="&strm_port=" +document.getElementById("idDVRCameraIP2Port_TX").value;
url+="&width=" +document.getElementById("idInfoWidth").innerHTML;
url+="&height="+document.getElementById("idInfoHeight").innerHTML;
url+="&fps="+ document.getElementById("idSpanFPS").innerHTML;
if ((v=parseFloat(document.getElementById("idDVRMaxFileSize_TX").value))>0) {
url+="&max_file_size="+ Math.round(v*1048510);
}
// alert("v="+v+"/"+document.getElementById("idDVRMaxFileSize_TX").value+"\n"+url);
} else if (document.DVR_state==DVR_state_stop) {
parseInt(document.sessions.session[document.videoFiles[document.videoFiles.length-1].s].stop_stream)
url+="&ses_id="+document.sessions.session[document.videoFiles[document.videoFiles.length-1].s].id; // id - text, here - OK
}
url+="&_time="+t.getTime();
checkBadUrl(url,"dvrRegister");
//
// Cross-domain xmlHTTPRequests do not work because of the security limitations in Mozilla (if not specially enabled in profile). We will use camera
// to re-transmit requests to the server and return the results back. It might be a waste, but xml files are supposed
// to be small ones.
// server URL should be IP, camera does not support DNS
//
//alert (url);
url=document.retransmitUrl+"?"+escape(url);
// document.title=url; //********************
DVRXMLHttpRequest(url);
}
function DVRXMLHttpRequest(url) {
document.lastDVRurl=url;
if (document.debug & 64) document.title=" url="+url;
if (document.debug & 512) document.title+=" "+url.substr(57,5);
//alert (url);
if(window.XMLHttpRequest) {
DVRDBxml_req = new XMLHttpRequest();
DVRDBxml_req.onreadystatechange = dvrRegister_rec;
DVRDBxml_req.open("GET", url, true);
DVRDBxml_req.send(null);
} else if(window.ActiveXObject) {
DVRDBxml_req = new ActiveXObject("Microsoft.XMLHTTP");
if(DVRDBxml_req) {
DVRDBxml_req.onreadystatechange = dvrRegister_rec;
DVRDBxml_req.open("GET", url, true);
DVRDBxml_req.send();
}
}
}
function dvrRegister_rec() {
if (typeof(DVRDBxml_req)=="undefined") return; //trying to fight "uncaught exceptions" (happens when camera is setting it's date)
if (DVRDBxml_req.readyState == 4) {
// only if "OK"
if (DVRDBxml_req.status == 200) { // if camera time was not set in advance, "uncaught exception" will be here
// ...processing statements go here...
dvrRegister_rec_got(); // **** back to main loop ****
} else {
DVRcursor("");
alert_once("There was a problem retrieving the XML data\nurl="+document.lastDVRurl+"\n result:\n" +
DVRDBxml_req.statusText);
}
}
}
function dvrRegister_rec_got() { // parse it here
// alert ("state="+document.DVR_state+"\n"+DVRDBxml_req.responseText)
if (document.debug & 512) document.title+=" dvrr="+document.DVR_state;
var i,n,l,j,s,id;
if (document.getElementById("idDVRServer_TX").value=="") { // try to get IP of this computer from the camera
if (DVRDBxml_req.responseXML.getElementsByTagName('REMOTE_ADDR' ).length>0) {
document.getElementById("idDVRServer_TX").value=DVRDBxml_req.responseXML.getElementsByTagName('REMOTE_ADDR' )[0].firstChild.nodeValue;
document.DVR_state=DVR_state_camTry;
dvrRegister();
} else {
DVRcursor("");
alert ("error trying to get IP of this computer from the camera\nurl="+document.lastDVRurl+"\n - returned:\n"+DVRDBxml_req.responseText);
}
return;
} else if (document.DVR_state==DVR_state_record) { // start record
if (DVRDBxml_req.responseXML.getElementsByTagName('id' ).length>0) {
i=parseInt(DVRDBxml_req.responseXML.getElementsByTagName('id' )[0].firstChild.nodeValue);
// alert ("dvrRegister_rec_got() id=="+i);
if (document.debug & 65536) document.title+=" rid="+i;
document.DVR_state=DVR_state_sessions;
document.dvrButton2Press=-1; // no buttons to simulate press to
document.DVRRetriesConfirmRecordLeft=document.DVRRetriesConfirmRecord; // maybe - not needed, but I suspect that record indicator sometimes did not come up (record did started) because of
// some delay on a server;
if (document.debug & 512) document.title+=" started";
dvrRegister();
} else {
DVRcursor("");
alert ("error starting a recording session\nurl="+document.lastDVRurl+"\n returned:\n"+DVRDBxml_req.responseText);
document.dvrButton2Press=-1; // no buttons to simulate press to
document.DVR_state=DVR_state_sessions;
}
return;
} else if (document.DVR_state==DVR_state_stop) { // stop record
if ((DVRDBxml_req.responseXML.getElementsByTagName('stop' ).length>0) && (DVRDBxml_req.responseXML.getElementsByTagName('stop' )[0].firstChild.nodeValue=="OK")) {
document.DVR_state=DVR_state_sessions;
document.dvrButton2Press=-1; // no buttons to simulate press to
document.DVRRetriesConfirmRecordLeft=-document.DVRRetriesConfirmRecord; // maybe - not needed, but I suspect that record indicator sometimes did not come up (record did started) because of
// some delay on a server;
if (document.debug & 512) document.title+=" stoped";
dvrRegister();
return;
} else {
DVRcursor("");
alert ("error terminating a recording session\nurl="+document.lastDVRurl+"\n returned:\n"+DVRDBxml_req.responseText);
document.dvrButton2Press=-1; // no buttons to simulate press to
document.DVR_state=DVR_state_sessions;
return;
}
} else if (document.DVR_state==DVR_state_camAdd) {
// alert(typeof (DVRDBxml_req.responseXML.getElementsByTagName('add' )));
// alert(DVRDBxml_req.responseXML.getElementsByTagName('add' ).toSource());
// alert(typeof (DVRDBxml_req.responseXML.getElementsByTagName('add' ).length));
// alert(DVRDBxml_req.responseXML.getElementsByTagName('add' ).length);
if ((typeof (DVRDBxml_req.responseXML.getElementsByTagName('add' ).length)=="undefined")||
(DVRDBxml_req.responseXML.getElementsByTagName('add' ).length==0)) {
id=document.getElementById(document.TABS_dvr.id).parentNode.id;
// show settings with the link to the DVR software download
document.divVisibility[id]="";
document.getElementById(id).style.display=document.divVisibility[id];
onClickTabs(document.TABS_dvr.id,document.TABS_dvr.n);
showWindow();
alert(document.getElementById("h_idDVRServerInstall").innerHTML);
document.DVR_state=DVR_state_camTry;
document.getElementById("idDVRSoftwareAll").style.display="";
return;
}
// was getting error if no server responded (or wrong server)
//Error: no element found
//Source File: http://192.168.0.9/xmlxmt.cgi?http%3A//192.168.0.18/vcr_lamp/camera.php%3Fcmd%3Dlist%26fmt%3Dxml%26mac%3D000E6404014A%26_time%3D1142468269396
//Line: 1, Column: 1
//Source Code:
if (DVRDBxml_req.responseXML.getElementsByTagName('add' )[0].firstChild.nodeValue=="OK") {
document.DVR_state=DVR_state_camReTry;
dvrRegister();
return;
} else {
DVRcursor("");
alert ("error adding camera to db\nurl="+document.lastDVRurl+"\nreturned:\n"+DVRDBxml_req.responseText);
return;
}
} else if (document.DVR_state == DVR_state_camEdit) { // edit
if (DVRDBxml_req.responseXML.getElementsByTagName('edit' )[0].firstChild.nodeValue=="OK") {
document.DVR_state = DVR_state_sessions;
// alert ("camera registered with the DVR server");
dvrRegister();
} else {
DVRcursor("");
alert ("error editing camera info in db\nurl="+document.lastDVRurl+"\nreturned:\n"+DVRDBxml_req.responseText);
}
return;
} else if (document.DVR_state == DVR_state_sessions) { // read sessions
document.getElementById("idDVRSoftwareAll").style.display="none"; // server is working, no need for the software
var n=DVRDBxml_req.responseXML.getElementsByTagName('session' ).length;
if (n>0) { // number of 'session' tags >0
// main parsing here
var lastSessions=parseXmlResponce(DVRDBxml_req.responseXML.getElementsByTagName('recorder')[0].childNodes);
if (typeof(lastSessions.session.length)=="undefined") { // just one session
lastSessions.session=new Array(lastSessions.session);
}
if (document.debug & 65536) document.title+=" ("+lastSessions.session.length+")";
if ((!document.sessions) || (document.sessions.session.length == 0)) {
document.sessions=lastSessions;
} else { // merge
i=(document.videoFiles.length>0)?document.videoFiles[document.videoFiles.length-1].s : 0;
for (j=0;j<lastSessions.session.length;j++) {
document.sessions.session[i++]=lastSessions.session[j];
}
}
processSessions();
if (document.debug & 512) document.title+=" btp="+document.dvrButton2Press;
if ((document.dvrButton2Press!=DVRRecord) &&(document.dvrButton2Press!=DVRStopRecord)) { // do not update record indicator before the on/off command is executed
dvrShowRecording();
}
DVRcursor(""); // is it OK to release here?
if (document.dvrButton2Press >= 0) {
dvrButtonContinue(document.dvrButton2Press); //continue with the button pressed that caused first registration
}
return; // ************************ everything is in sync with DB *******************************
} else { //zero length
DVRcursor("");
// below - it can just be OK - just empty database
// alert ("problems reading session info\nurl="+document.lastDVRurl+"\nreturned:\n"+DVRDBxml_req.responseText+"\nIt can be OK - just a new database with no records");
document.title="**** Empty database ****";
// try to make an empty session (OK for recording)
document.sessions={session:new Array()};
processSessions();
if ((document.dvrButton2Press!=DVRRecord) &&(document.dvrButton2Press!=DVRStopRecord)) { // do not update record indicator before the on/off command is executed
dvrShowRecording();
}
DVRcursor(""); // is it OK to release here?
if (document.debug & 64) document.title+=" <"+document.dvrButton2Press+">";
if (document.dvrButton2Press >= 0) {
dvrButtonContinue(document.dvrButton2Press); //continue with the button pressed that caused first registration
}
return; // ************************ everything is in sync with DB *******************************
}
} else if ((document.DVR_state==DVR_state_camTry) || (document.DVR_state==DVR_state_camReTry)) {
if (DVRDBxml_req.responseXML.getElementsByTagName('camera' ).length>0) { // number of 'camera' tags >0 (we now are interested in just 1)
// main parsing here
document.cameraDbInfo={};
l=DVRDBxml_req.responseXML.getElementsByTagName('camera' )[0].childNodes.length;
for (j=0;j<l;j++) {
// alert ("l="+l+" j="+j+"\n"+DVRDBxml_req.responseXML.getElementsByTagName('camera' )[0].childNodes[j].nodeName);
if (DVRDBxml_req.responseXML.getElementsByTagName('camera' )[0].childNodes[j].nodeName !="#text") {
document.cameraDbInfo[DVRDBxml_req.responseXML.getElementsByTagName('camera' )[0].childNodes[j].nodeName]=
DVRDBxml_req.responseXML.getElementsByTagName('camera' )[0].childNodes[j].childNodes.length?
unescape(unescape(DVRDBxml_req.responseXML.getElementsByTagName('camera' )[0].childNodes[j].childNodes[0].nodeValue)):"";
}
}
if ((document.cameraDbInfo.ip1!="") && (document.getElementById("idDVRCameraIP1_TX").value=="")) document.getElementById("idDVRCameraIP1_TX").value=document.cameraDbInfo.ip1;
if ((document.cameraDbInfo.place!="") && (document.getElementById("idDVRLocation_TX").value =="") ) document.getElementById("idDVRLocation_TX").value=document.cameraDbInfo.place;
document.DVR_state=DVR_state_camEdit;
dvrRegister();
return;
} else {
if (document.DVR_state==DVR_state_camTry) {
document.DVR_state=DVR_state_camAdd;
dvrRegister(); // run "add camera"
return;
} else {
DVRcursor("");
alert ("Error: could not list camera after adding it");
return;
}
}
} else {
DVRcursor("");
alert("unexpected state of in dvrRegister_rec_got() document.DVR_state - "+document.DVR_state);
return;
}
}
function dvrShowRecording() {
if (document.videoFiles.length>0) {
var lastSes=document.videoFiles[document.videoFiles.length-1].s;
if (parseInt(document.sessions.session[lastSes].stop_stream)==0) { // recording in progress
setBuTtonState("btnDVRRecord", 1);
setBuTtonState("btnDVRRecord_L", 1);
document.getElementById("idRecOff").style.display="none";
document.getElementById("idRecOn").style.display="";
document.getElementById("idDVRRecordingSinceAll").style.color="#ff0000";
document.getElementById("idDVRRecordingSince").innerHTML=printDateTime(fromEpoch (parseInt(document.sessions.session[lastSes].start_stream)));
} else {
setBuTtonState("btnDVRRecord", 0);
setBuTtonState("btnDVRRecord_L", 0);
document.getElementById("idRecOff").style.display="";
document.getElementById("idRecOn").style.display="none";
document.getElementById("idDVRRecordingSinceAll").style.color="";
document.getElementById("idDVRRecordingSince").innerHTML="---";
}
} else {
setBuTtonState("btnDVRRecord", 0);
setBuTtonState("btnDVRRecord_L", 0);
document.getElementById("idRecOff").style.display="";
document.getElementById("idRecOn").style.display="none";
document.getElementById("idDVRRecordingSinceAll").style.color="";
document.getElementById("idDVRRecordingSince").innerHTML="---";
}
}
function dvrShowStartStopping(strt) { // 1 - show starting, 0 - show stopping
if (strt) { // recording in progress
setBuTtonState("btnDVRRecord", 1);
setBuTtonState("btnDVRRecord_L", 1);
// document.getElementById("idRecOff").style.display="none";
// document.getElementById("idRecOn").style.display="";
document.getElementById("idDVRRecordingSinceAll").style.color="#ff0000";
document.getElementById("idDVRRecordingSince").innerHTML="starting...";
} else {
setBuTtonState("btnDVRRecord", 0);
setBuTtonState("btnDVRRecord_L", 0);
// document.getElementById("idRecOff").style.display="";
// document.getElementById("idRecOn").style.display="none";
document.getElementById("idDVRRecordingSinceAll").style.color="#ff0000";
document.getElementById("idDVRRecordingSince").innerHTML="stopping...";
}
}
// will skip all text except the terminal strings in tags
function parseXmlResponce(xmlObj) {
var n,i,nam,t,j;
// var nm;
n=xmlObj.length;
// if (!(n>0)) return null; // "undefined" OK too
if (!(n>0)) return ""; // "undefined" OK too
if ((n==1) && (xmlObj[0].nodeName =="#text")) return xmlObj[0].nodeValue;
var obj={};
j=0;
for (i=0;i<n;i++) if ((nam=xmlObj[i].nodeName) !="#text") {
if ((t=typeof(obj[nam]))=="undefined") { // new named element
j++;
// nm=nam;
obj[nam]= parseXmlResponce(xmlObj[i].childNodes);
} else if ( obj[nam].length>1) obj[nam][obj[nam].length]= parseXmlResponce(xmlObj[i].childNodes);
else obj[nam]= new Array (obj[nam], parseXmlResponce(xmlObj[i].childNodes)); // was text, not array
}
// if (j==0) return null;
if (j==0) return "";
else return obj;
}
//document.videoFiles=new Array(0);
function processSessions() {
var i,j,tx,k;
var sorted,ep0;
var ts;
var f;
document.videoFiles=new Array(0);
// alert(document.sessions.session.toSource());
for (i=0; i<document.sessions.session.length;i++) {
// document.title+=" "+i+"/"+document.sessions.session[i].files.file.length;
if (typeof (document.sessions.session[i].files.file)=="undefined") {
document.sessions.session[i].files={file:new Array(0)}; // no files in a session
} else if (typeof (document.sessions.session[i].files.file.length)=="undefined") {
document.sessions.session[i].files.file=new Array(document.sessions.session[i].files.file);
}
sorted=true; // session files seem to be sorted, but is it always so?
ep0=0;
// alert(document.sessions.session[i].toSource());
for (j=0;j<document.sessions.session[i].files.file.length;j++) {
tx=document.sessions.session[i].files.file[j].url;
// remove directory part and ".ogm" (only one dot)
while ((k=tx.indexOf("/"))>=0) tx=tx.substr(k+1);
tx=tx.substr(0,tx.indexOf("."));
tx=tx.split("-");
//alert (tx.toSource());
// tx=tx.substr(tx.indexOf(".")-15,15);
// document.sessions.session[i].files.file[j].epoch=toEpoch (textToDate(tx));
document.sessions.session[i].files.file[j].epoch= toEpoch (textToDate(tx[0]+"-"+tx[1]));
document.sessions.session[i].files.file[j].epochEnd=toEpoch (textToDate(tx[2]+"-"+tx[3]));
document.sessions.session[i].files.file[j].dur=document.sessions.session[i].files.file[j].epochEnd-document.sessions.session[i].files.file[j].epoch;
document.sessions.session[i].files.file[j].frames= parseInt(tx[4]);
if (document.sessions.session[i].files.file[j].epoch<ep0){
// alert ("unsorted, "+document.sessions.session[i].files.file[j].epoch+"<"+ ep0 +" i="+i+" j="+j+"\n"+document.sessions.session[i].toSource());
sorted=false;
}
ep0=document.sessions.session[i].files.file[j].epoch;
}
if (!sorted) {
// alert ("Session files are not sorted - please add the sorting code to camvc_dvr.js");
// debugWindowShow(document.sessions.toSource());
while (!sorted) {
sorted=true;
for (j=0;j<(document.sessions.session[i].files.file.length-1);j++) {
if (document.sessions.session[i].files.file[j+1].epoch < document.sessions.session[i].files.file[j].epoch) {
f=document.sessions.session[i].files.file[j+1];
document.sessions.session[i].files.file[j+1]=document.sessions.session[i].files.file[j];
document.sessions.session[i].files.file[j]=f;
sorted=false;
}
}
}
}
// includes possible time zone difference and latency
if (document.sessions.session[i].files.file.length>0) {
/*
ts=document.sessions.session[i].files.file[0].epoch-parseInt(document.sessions.session[i].start_stream);
for (j=0;j<document.sessions.session[i].files.file.length-1;j++) {
document.sessions.session[i].files.file[j].dur=document.sessions.session[i].files.file[j+1].epoch-document.sessions.session[i].files.file[j].epoch; //(might be 0)
}
document.sessions.session[i].files.file[document.sessions.session[i].files.file.length-1].dur=
parseInt(document.sessions.session[i].stop_stream) + ts -
document.sessions.session[i].files.file[document.sessions.session[i].files.file.length-1].epoch; //<0 - unfinished
*/
for (j=0;j<document.sessions.session[i].files.file.length;j++) {
document.videoFiles[document.videoFiles.length]={s:i,f:j};
}
}
}
// alert ("document.videoFiles.length="+document.videoFiles.length+"\n"+document.videoFiles.toSource());
if (document.videoFiles.length>0) {
if (document.DVR_fileNum.len!=document.videoFiles.length) { // number of files actually changed since last time
document.DVR_fileNum.len=document.videoFiles.length;
if (document.DVR_fileNum.n<0) { // only if was not registered before
document.DVR_fileNum.n=document.DVR_fileNum.len-1; // point to last record
}
if (document.videoFiles.length>1) {
setSliderHigh("idDVRSlider_slIder",document.DVR_fileNum.len-1);
setSliderAndText("idDVRSlider_slIder", document.DVR_fileNum.n); // needed in any case - slider should be redrawn even if only .len changed, not .n
document.divVisibility["idDVRSlider"]="";
document.getElementById("idDVRSlider").style.display="";
enableSlider("idDVRSlider_slIder",1);
showWindow();
}
}
} else {
document.divVisibility["idDVRSlider"]="none";
document.getElementById("idDVRSlider").style.display="none";
document.DVR_fileNum.len=-1;
document.DVR_fileNum.n=-1;
enableSlider("idDVRSlider_slIder",0); //disable until registered OK
}
showDVRInfoAll();
}
function dvrPositionOnFile() {
// setSliderAndText("idDVRSlider_slIder", document.DVR_fileNum.n);
document.DVR_fileNum.n= parseInt(getSliderValue("idDVRSlider_slIder"));
showDVRInfoAll();
if (document.dvrWasVideoState==DVRVideoStatePlay) dvrStartPlay(); // play
}
function resetDVRPlay() {
alert("stop and rewind file");
}
// ******************************
/*
document.videoFiles=new Array(0);
document.sessions=null;
document.DVR_state=DVR_state_camTry;
//document.DVR_fileNum={ses:-1,fil:0,pos:0};
document.DVR_fileNum={n:-1,fil:0,pos:0};
*/
function nextDVRfile () { //return true if bumps;
if (document.DVR_fileNum.n<0) return true;
document.DVR_fileNum.n++;
if (document.DVR_fileNum.n >= document.videoFiles.length) {
document.DVR_fileNum.n--;
return true;
}
setSliderAndText("idDVRSlider_slIder", document.DVR_fileNum.n);
showDVRInfoAll();
return false;
}
function prevDVRfile () { //return true if bumps;
if (document.DVR_fileNum.n<0) return true;
document.DVR_fileNum.n--;
if (document.DVR_fileNum.n <0) {
document.DVR_fileNum.n=0;
return true;
}
setSliderAndText("idDVRSlider_slIder", document.DVR_fileNum.n);
showDVRInfoAll();
return false;
}
//********************************************
function showDVRInfoAll() {
var furl="http://"+document.getElementById("idDVRServer_TX").value;
if (document.getElementById("idDVRServerPort_TX").value!="") furl+=":"+document.getElementById("idDVRServerPort_TX").value;
var ss,f;
//
if (document.videoFiles.length>0) {
with (document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].files.file[document.videoFiles[document.DVR_fileNum.n].f]) {
var nm=name;
//document.title+=" "+nm+ " "+furl;
if (nm.length > 20) nm=nm.substr(0,3)+"..."+nm.substr(nm.length-14,14);
document.getElementById("idDVRFileShortName").innerHTML=nm;
document.getElementById("idDVRLink_LN").href=furl+url;
document.getElementById("idDVRFileSize").innerHTML=Math.round(parseFloat(size)/10000)/100;
document.getElementById("idDVRFileStart").innerHTML=(ss=printDateTime(fromEpoch (epoch)));
document.getElementById("idDVRStart_TX").value=ss;
if (dur>0) {
document.getElementById("idDVRFileEnd").innerHTML=printDateTime(fromEpoch (epoch+dur));
document.getElementById("idDVRFileDuration").innerHTML=printTime(fromEpoch (dur));
} else if (dur==0) {
document.getElementById("idDVRFileEnd").innerHTML=printDateTime(fromEpoch (epoch));
document.getElementById("idDVRFileDuration").innerHTML="< 1 sec";
} else { // <0
document.getElementById("idDVRFileEnd").innerHTML="???";
document.getElementById("idDVRFileDuration").innerHTML="???";
}
if (frames>=0) {
document.getElementById("idDVRFileFrames").innerHTML=frames;
} else { // <0
document.getElementById("idDVRFileFrames").innerHTML="???";
}
}
with (document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s]) {
if (typeof(file_format) != "undefined" )document.getElementById("idDVRFileFormat").innerHTML= file_format;
document.getElementById("idDVRFrameWidth").innerHTML= width;
document.getElementById("idDVRFrameHeight").innerHTML=height;
document.getElementById("idDVRFPS").innerHTML=((f=parseFloat(fps))>0)?f:"---";
}
}
showDVRInfoPos();
// showWindow(); // if the
}
document.lastPlaybackPosition=0;
function showPlaybackPosition(v) {
v=Math.round(v);
if (document.lastPlaybackPosition !=v) {
document.lastPlaybackPosition=v;
document.getElementById("idDVRFilePosition").innerHTML=printTime(fromEpoch (v));
return true;
}
return false;
}
function showDVRInfoPos() {
document.getElementById("idDVRFilePosition").innerHTML=printTime(fromEpoch (document.DVR_fileNum.pos));
}
function searchVideoFile() {
var i,j,e;
var s0= document.getElementById("idDVRStart_TX").value;
var s=""
for (i=0;i<s0.length;i++) {
if (" -:/".indexOf(s0.substr(i,1))>=0) {
s+=" ";
} else {
s+=s0.substr(i,1);
}
}
s=s.split(" ");
j=0;
for (i=0;i<s.length;i++) {
if (s[i]!="") {
if (i>j) s[j]=s[i];
j++;
}
}
j--;
// dt=fromEpoch (document.sessions.session[document.DVR_fileNum.ses].files.file[document.DVR_fileNum.fil].epoch);
dt=fromEpoch (document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].files.file[document.videoFiles[document.DVR_fileNum.n].f].epoch);
//document.title="j="+j+ " s="+s.toSource();
if (j>=0) {
dt.s=parseInt(s[j--]);
//document.title+=" dt.s="+dt.s;
if ((dt.s<0) || (dt.s>59)) return false;// do nothing
}
if (j>=0) {
dt.n=parseInt(s[j--]);
//document.title+=" dt.n="+dt.n;
if ((dt.n<0) || (dt.n>59)) return false;// do nothing
}
if (j>=0) {
dt.h=parseInt(s[j--]);
//document.title+=" dt.h="+dt.h;
if ((dt.h<0) || (dt.h>23)) return false;// do nothing
}
if (j>=0) {
dt.y=parseInt(s[j--]);
//document.title+=" dt.y="+dt.y;
if (dt.y<1970) return false;// do nothing
}
if (j>=0) {
dt.d=parseInt(s[j--]);
//document.title+=" dt.d="+dt.d;
if ((dt.d<0) || (dt.d>31)) return false;// do nothing
}
if (j>=0) {
dt.m=parseInt(s[j--]);
//document.title+=" dt.m="+dt.m;
if ((dt.m<0) || (dt.m>11)) return false;// do nothing
}
e=toEpoch(dt);
// document.title+=" e="+e+" dt="+dt.toSource();
// stopStreamPlayback();
//******************************************************
// if (document.DVR_fileNum.n=>document.videoFiles.length) {
// createVideoSlider(w-200,document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].files.file[document.videoFiles[document.DVR_fileNum.n].f].dur);
// document.DVR_fileNum={ses:0,fil:0,pos:0};
for (document.DVR_fileNum.n=0;document.DVR_fileNum.n<document.videoFiles.length;document.DVR_fileNum.n++) {
// document.title+=" " +document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].files.file[document.videoFiles[document.DVR_fileNum.n].f].epoch;
if (document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].files.file[document.videoFiles[document.DVR_fileNum.n].f].epoch >= e) {
setSliderAndText("idDVRSlider_slIder", document.DVR_fileNum.n);
showDVRInfoAll();
if (document.dvrWasVideoState==DVRVideoStatePlay) dvrStartPlay(); // play
return true;
}
}
//document.title+=" >- document.DVR_fileNum.n="+document.DVR_fileNum.n;
setSliderAndText("idDVRSlider_slIder", document.DVR_fileNum.n);
showDVRInfoAll();
if (document.dvrWasVideoState==DVRVideoStatePlay) dvrStartPlay(); // play
return true;
}
//*****************************************************
/*
var DVRVideoStateStop= 0;
var DVRVideoStateLive= 1;
var DVRVideoStateLiveP=2;
var DVRVideoStatePlay= 3;
var DVRVideoStatePlayP=4;
*/
document.dvrWasVideoState=0;
document.dvrButton2Press;
function onPlayerRun() {
if (parseInt(document.getElementById("idVideoObject").run)==0) {
if (getBuTton("idDVRLoop_CB").s) {
document.getElementById("idVideoObject").run=1; // (run again)
} else if (getBuTton("idDVRNextPlay_CB").s){
document.dvrWasVideoState=DVRVideoStatePlay;
document.enableForwardRetry=true;
dvrButtonContinue (5); // forward
} else {
dvrButton (4); // stop
}
}
}
// if ((dvrVideoState()== DVRVideoStatePlay) || (dvrVideoState()== DVRVideoStatePlayP))
function dvrVideoState() { // 0 - off, 1 - live, 2 live pause (not yet used), 3 - playing, 4 pause
if ((!document.getElementById("idVideoObject")) || (typeof(document.getElementById("idVideoObject").pause)=="undefined")) return DVRVideoStateStop;
var p=parseInt (document.getElementById("idVideoObject").pause);
var l= document.getElementById("idVideoObject").href;
l= (l.indexOf("rtp://")>=0) || (l.indexOf("rtsp://")>=0);
if (l && !p) return DVRVideoStateLive;
if (l && p) return DVRVideoStateLiveP;
if (!p) return DVRVideoStatePlay;
return DVRVideoStatePlayP;
}
function dvrStartPlay() {
//document.sessions.session[document.videoFiles[document.DVR_fileNum.n]
vw=parseInt(document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].width);
vh=parseInt(document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].height);
if (!(vh>1)) { // just something non-0 not to get stuck with zero-size
vw=1024;
vh=768;
}
url=document.getElementById("idDVRLink_LN").href;
makeStreamPlayback(vw,vh,url);
}
function DVRButtonReady() {
return ((document.getElementById("idDVRInfo").style.cursor != "wait") || document.shiftKey);
}
function dvrButton (n) { //
if (document.debug & 512) document.title=n;
document.enableForwardRetry=true;
document.dvrWasVideoState=dvrVideoState();
var id;
var vw, vh, url;
if (!DVRButtonReady()) {
if (document.debug & 65536) document.title+=" ?";
dvrShowRecording(); // return the buttons as they should be
return;
}
if ((n != DVRList) && (n != DVRSettings)) {
if ((document.sessions==null) || (n==DVRRecord) || (n==DVRStopRecord)) { // will try to make automatic registration with default address (make a script in the camera to find out local "my" address)
// localhost will not work - need real address as camera sees it
// always re-register for record/stop record commands to have up-to-date session info
if (n==DVRRecord) dvrShowStartStopping(1);
else if (n==DVRStopRecord) dvrShowStartStopping(0);
document.dvrButton2Press=n;
// alert("You need to register at the DVR server to be able to use it");
dvrRegister();
return;
}
}
document.DVRRetriesConfirmRecordLeft=0; //
dvrButtonContinue (n);
}
function dvrButtonContinue (n) { // come here from the code, not just from the user command
if ((document.sessions==null) && (n != DVRList) && (n != DVRSettings) ) {
alert ("Unable to perform the command - could not register at DVR");
return;
}
if (n==DVRRecord) { //record
document.DVR_state=DVR_state_record;
document.dvrButton2Press=n;
dvrRegister();
} else if (n==DVRStopRecord){ //stop record
document.DVR_state=DVR_state_stop;
document.dvrButton2Press=n;
dvrRegister();
} else if (n==DVRBack){ //back
// if ((dvrVideoState()==DVRVideoStatePlay) || (dvrVideoState()==DVRVideoStatePlayP)) stopStreamPlayback();
prevDVRfile ();
if (document.dvrWasVideoState==DVRVideoStatePlay) dvrStartPlay(); // play
} else if (n==DVRForward){ //forward
// if ((dvrVideoState()==DVRVideoStatePlay) || (dvrVideoState()==DVRVideoStatePlayP)) stopStreamPlayback();
if (nextDVRfile ()) {
if (!document.enableForwardRetry) {
if ((dvrVideoState()== DVRVideoStatePlay) || (dvrVideoState()== DVRVideoStatePlayP)) stopStreamPlayback(); // just stop
} else { // try re-register to get new files if any
document.dvrButton2Press=n;
document.enableForwardRetry=false; // will not loop if no new records
dvrRegister();
}
} else {
if (document.dvrWasVideoState==DVRVideoStatePlay) dvrStartPlay(); // play
}
} else if (n==DVRPlay){ //play
if (dvrVideoState()==DVRVideoStatePlayP) {
document.getElementById("idVideoObject").pause=0;
document.getElementById("idVideoR").innerHTML="R";
} else {
dvrStartPlay();
}
} else if (n==DVRPause){ //pause
if (parseInt(document.getElementById("idVideoObject").pause)>0) {
document.getElementById("idVideoObject").pause=0;
document.getElementById("idVideoR").innerHTML="R";
} else {
document.getElementById("idVideoObject").pause=1;
document.getElementById("idVideoR").innerHTML="P";
}
} else if (n==DVRStop){ //stop
stopStreamPlayback();
} else if (n==DVRList) { // list
id="idDivDVR";
if (document.getElementById(id).style.display=="") {
document.divVisibility[id]="none";
document.getElementById(id).style.display=document.divVisibility[id];
} else {
document.divVisibility[id]="";
document.getElementById(id).style.display=document.divVisibility[id];
}
showWindow();
} else if (n==DVRSettings) { // settings
id=document.getElementById(document.TABS_dvr.id).parentNode.id;
if ((document.getElementById(id).style.display=="") && (getSelectedTab(document.TABS_dvr.id)==document.TABS_dvr.n)) {
document.divVisibility[id]="none";
document.getElementById(id).style.display=document.divVisibility[id];
} else {
document.divVisibility[id]="";
document.getElementById(id).style.display=document.divVisibility[id];
onClickTabs(document.TABS_dvr.id,document.TABS_dvr.n);
}
showWindow();
} else if (n==DVRSearch) { // search
searchVideoFile();
// alert("was search");
} else {
}
}
/*
{id:"btnDVRRecord", n:73, t:"T2",dm:"", aoer:"dvrButton(getBuTton(id).s?6:9);",aolr:"*"},
{id:"btnDVRRecord_L", n:73, t:"T2",dm:"", aoer:"dvrButton(getBuTton(id).s?6:9);",aolr:"*"},
{id:"btnDVRStopRecord", n:71, t:"b",dm:"", aoer:"dvrButton(9);",aolr:"*"},
// setBuTtonState("idAexpOn_CB", !getBuTton("idAexpOn_CB").s);
*/
//http://www.comptechdoc.org/independent/web/cgi/javamanual/javadate.html
/*
* Date() - Use the current date and time to create an instance of the object date.
* Date(dateString) - Use the date specified by the string to create the instance of the date object. String format is "month day, year hours:minutes:seconds".
* Date(year, month, day) - Create an instance of date with the specified values. Year is 0 to 99.
* Date(year, month, day, hours, minutes, seconds) - Create an instance of date with the specified values.
# getDate() - Get the day of the month. It is returned as a value between 1 and 31.
# getDay() - Get the day of the week as a value from 0 to 6
# getHours() - The value returned is 0 through 23.
# getMinutes() - The value returned is 0 through 59.
# getMonth() - Returns the month from the date object as a value from 0 through 11.
# getSeconds() - The value returned is 0 through 59.
# getTime() - The number of milliseconds since January 1, 1970. this function allows you to manipulate the date object based on a millisecond value then convert it back to the form you want. In the example below, it is # getTimeZoneOffset() - Time zone offset in hours which is the difference between GMT and local time.
# getYear() - Returns the numeric four digit value of the year.
# parse() - The number of milliseconds after midnight January 1, 1970 till the given date espressed as a string in the example which is IETF format.
var curdate = "Wed, 18 Oct 2000 13:00:00 EST"
# setDate(value) - Set the day of the month in the date object as a value from 1 to 31.
# setHours(value) - Set the hours in the date object with a value of 0 through 59.
# setMinutes(value) - Set the minutes in the date object with a value of 0 through 59.
# setMonth(value) - Set the month in the date object as a value of 0 through 11.
# setSeconds(value) - Set the seconds in the date object with a value of 0 through 59.
# setTime(value) - Sets time on the basis of number of milliseconds since January 1, 1970. The below example sets the date object to one hour in the future.
*/
// TODO: change date/time manipulation to standard functions listed above
//num22chr(n)
document.months=new Array (31,28,31,30,31,30,31,31,30,31,30,31);
//date <->epoch - no time zone, no daylight savings.
function textToDate (tx) { //yyyymmdd-hhmmss
var dt={y:0,m:0,d:0,h:0, n:0, s:0};
with (dt) {
y=parseInt(tx.substr(0,4),10);
m=parseInt(tx.substr(4,2),10);
d=parseInt(tx.substr(6,2),10);
h=parseInt(tx.substr(9,2),10);
n=parseInt(tx.substr(11,2),10);
s=parseInt(tx.substr(13,2),10);
}
return dt;
}
function toEpoch (dat) { //{y,m,d,h,n,s}
with (dat) {
var dd=365*(y-1970)+Math.floor((y-1969)/4)+ (d-1);
var i; for (i=1;i<m;i++) dd+=document.months[i-1];
if ((y==(4*Math.floor(y/4))) && (m>2)) dd++;
return dd*86400+h*3600+n*60+s;
}
}
function fromEpoch (epoch) { //yyyymmdd-hhmmss
var dt={y:0,m:0,d:0,h:0, n:0, s:0};
with (dt) {
d=Math.floor(epoch/86400);
s=epoch-86400*d;
h=Math.floor(s/3600);
s-=h*3600;
n=Math.floor(s/60);
s-=n*60;
var y4=Math.floor(d/1461);
d-= y4*1461;
y=1970+4*y4;
var lp=0;
if (d>=365) {
y++;d-=365;
if (d>=365) {
y++;d-=365;
if (d>=366) {
y++;d-=366;
} else lp=1;
}
}
var dm;
for (m=1; d >= (dm=(document.months[m-1]+(((m==2) && lp)? 1:0))); d-=dm) m++;
d++;
}
return dt;
}
function num22chr(n) {
var s=""+n;
if (s.length<2) s="0"+s;
return s;
}
function printDateTime(dt){
return ((dt.m<10)?"0":"")+dt.m+"/"+((dt.d<10)?"0":"")+dt.d+"/"+dt.y+" "+
((dt.h<10)?"0":"")+dt.h+":"+((dt.n<10)?"0":"")+dt.n+":"+((dt.s<10)?"0":"")+dt.s;
}
function printTime(dt){
return ((dt.h<10)?"0":"")+dt.h+":"+((dt.n<10)?"0":"")+dt.n+":"+((dt.s<10)?"0":"")+dt.s;
}
/*
*! -----------------------------------------------------------------------------**
*! FILE NAME : camvc_interface.js
*! DESCRIPTION: Provides connection between ajax camera communication and camvc
*! interface elements
*! Copyright (C) 2008 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvc_interface.js,v $
*! Revision 1.18 2010/08/01 19:30:24 elphel
*! new readonly parameter FRAME_SIZE and it support in the applications
*!
*! Revision 1.17 2010/06/08 21:47:39 elphel
*! fixed new bug in regular cameras caused by multi-sensor additions
*!
*! Revision 1.16 2010/06/06 04:27:26 elphel
*! Fixed updating of flipX/flipY checkboxes when the orientation is changed in the camera (or flip* was set when the program started)
*!
*! Revision 1.15 2010/06/04 01:56:51 elphel
*! Initial support for the multi-sensor operation
*!
*! Revision 1.14 2008/12/13 23:38:42 elphel
*! Support fro SnapFulll button
*!
*! Revision 1.13 2008/12/11 07:24:35 elphel
*! debug output (commented out anyway)
*!
*! Revision 1.12 2008/12/11 06:39:11 elphel
*! reduced number of unneeded requests, corrected start when the compressor is stopped
*!
*! Revision 1.11 2008/12/10 22:09:37 elphel
*! Skipping histogram refresh (and hiding it) when compressor is stopped (fro circbuf navigation)
*!
*! Revision 1.10 2008/12/09 22:11:56 elphel
*! Fixed resizing, changed color/mono checkbox to mode selector
*!
*! Revision 1.9 2008/12/09 07:51:52 elphel
*! Partial support of ccam.ftp added alerts on non-yet-ported control tabs. Temporary launches autocampars to save selected parameters fro next autostart
*!
*! Revision 1.8 2008/12/07 23:07:17 elphel
*! Fixing few remaining "fights" between user and the camera (when some parameter is changed and camera changes it back)
*!
*! Revision 1.7 2008/12/05 08:10:19 elphel
*! Fixed work (at least seems so) circbuf+Exif operation
*!
*! Revision 1.6 2008/12/05 03:31:31 elphel
*! Multiple changes, some cleanup and working on restoring circbuf/Exif functionality available in 7.1
*!
*! Revision 1.5 2008/12/04 02:24:46 elphel
*! Adding/debugging autoexposure controls
*!
*! Revision 1.4 2008/12/02 01:10:30 elphel
*! fixed white balance color correction sliders
*!
*! Revision 1.3 2008/12/02 00:28:13 elphel
*! multiple bugfixes, making white balance to work and work with camvc
*!
*! Revision 1.2 2008/12/01 07:33:03 elphel
*! Added gains, scales, white balance control
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.4 2008/11/16 17:35:53 elphel
*! restored histogram (autoexposure) window control
*!
*! Revision 1.3 2008/11/10 19:55:51 elphel
*! 8.0.alpha15 - first camvc working with 8.0 (just basic features - no autoexposure, white balance, ...), but it is now really possible (again after it was broken for quite a while) to move sliders and navigator windows without fighting with the camera that tried to move them back
*!
*! Revision 1.2 2008/11/08 23:59:23 elphel
*! snapshot
*!
*! Revision 1.1 2008/11/08 05:54:02 elphel
*! snapshot - working on camvc
*!
*!
*/
var gInterface;
document.dcm={dh:0,dv:0,bh:0,bv:0,dhs:0,dvs:0,bhs:0,bvs:0}; // waiting for camera to respond
document.multisensor={msens:0,mseq:0,mmod:0,msel:0};
function initInterface() {
var i;
initParams(camParamsList);
gInterface=new camInterface(gPRoot,gRequests);
gRequests.setInterfacePointers(gInterface.gotShadow,gInterface.gotHistogram);
// requestsNextState(false);
}
function camInterface(proot,req) {
// this.pRoot= proot;
// this.requests=req;
this.imgPort="8081";
}
function toggleCompressorRun() {
if (gPRoot["comp_run"].getValue() == 'run') {
circbufRun(false);
gPRoot["comp_run"].setValue("stop");
hideStreamPage();
} else {
circbufRun(true);
gPRoot["comp_run"].setValue("run");
}
gInterface.onCompSensRun(); /// to reduce latency - will be updated when data received from the camera
}
camInterface.prototype.onCompSensRun= function () {
var isRunning=(gPRoot["comp_run"].getValue()=="run") && (gPRoot["sens_run"].getValue()=="run");
updateCircbufControls();
ignoreStreamerShow();
if (gPRoot["comp_run"].getValue() == 'run') {
document.getElementById("idInfoLabelRunning").style.display="";
document.getElementById("idInfoLabelStopped").style.display="none";
if ( (getBuTton('idEnableHist_CB').s !=0 ) && (document.getElementById("idDivHist").style.display == 'none')) {
document.divVisibility['idDivHist']='';
showWindow();
}
} else {
document.getElementById("idInfoLabelRunning").style.display="none";
document.getElementById("idInfoLabelStopped").style.display="";
if (document.getElementById("idDivHist").style.display != 'none') {
document.divVisibility['idDivHist']='none';
showWindow();
}
}
};
// called when histogram controls are updated
function updateHistControls() {
// if (document.histogramEnabled) {
if (getBuTton('idEnableHist_CB').s!=0) {
if ((gPRoot["comp_run"].getValue() == 'run') && (document.getElementById("idDivHist").style.display == 'none')) {
document.divVisibility['idDivHist']='';
showWindow();
setBuTtonState("idEnableHist_CB",true); /// hack - fighting control that slides out of the mouse when histogram window opens
// alert ("set to 1! - "+getBuTton('idEnableHist_CB').s);
// alert ("set to 1! - "+getBuTton('idEnableHist_CB').s);
}
gInterface.makeHistURL();
startRefresh();
}
}
function enableImageRefreshClicked(){imageHistEnableClicked();}
function imageHistEnableClicked() {
var imageEnabled=(getBuTton("idEnableImageRefresh_CB").s!=0);
// document.histogramEnabled=document.getElementById("idCBEnableHistogramRefresh").checked;
// if ((document.getElementById("idCBEnableImageRefresh").checked &&
if ((imageEnabled &&
!document.imageIsCurrent &&
(document.getElementById("idDivCameraImage").style.display != 'none')) ||
((getBuTton('idEnableHist_CB').s!=0) &&
!document.histogramIsCurrent &&
(document.getElementById("idDivHist").style.display != 'none'))) startRefresh ();
// document.EnableHist_CB_state=getBuTton('idEnableHist_CB').s;
}
/*
function imageHistEnableReleased() {
setBuTtonState("idEnableHist_CB",document.EnableHist_CB_state);
}
*/
// setBuTtonState("idEnableHist_CB",document.histogramEnabled);
// document.histogramEnabled=document.getElementById("idCBEnableHistogramRefresh").checked;
//{id:"idEnableHist_CB", n:30, t:"T2",dm:"", aop:"document.hist.enable=(getBuTton(id).s!=0);updateHistControls();"},
// document.divVisibility[id]="none";
// (document.getElementById("idDivHist").style.display != 'none'))) startRefresh ();
camInterface.prototype.onSensor= function () {
document.sensorID= gPRoot['SENSOR'].getValue();
if (document.sensorID) {
document.sensorType= gPRoot['sensor'].getValue();
// parse sensor type/specs
document.getElementById("idSensorWidth").innerHTML="<b>"+gPRoot['SENSOR_WIDTH'].getValue()+"</b>";
document.getElementById("idSensorHeight").innerHTML="<b>"+gPRoot['SENSOR_HEIGHT'].getValue()+"</b>";
document.decimationXMask=gPRoot['decXmask'].getValue();
document.decimationYMask=gPRoot['decYmask'].getValue();
document.binningXMask= gPRoot['binXmask'].getValue();
document.binningYMask= gPRoot['binYmask'].getValue();
} else {
document.sensorType= "none";
}
document.getElementById("idSensorType").innerHTML="<b>"+document.sensorType+"</b>";
document.multisensor.msens=gPRoot['msens'].getValue();
showMultiVisibility ("idMultiSensor",document.multisensor.msens);
};
camInterface.prototype.onFPS= function () {
document.sensorFPS=gPRoot['fps'].getValue();
document.getElementById("idSpanFPS").innerHTML=document.sensorFPS;
setInfoFPS();
document.skipStatusData=0;
var fpslm=gPRoot['fpsflags'].getValue();
// when the following lines are enabled, they overwrite variables too soon. But it is still better to fix functionality
// so changing from another computer will chnage here too
//TODO: still fires to early and overwrites user selection - find out why
document.fpslim=(fpslm & 1)?1:0;
document.fpsmtn=(fpslm & 2)?1:0;
showFPSLimit();
}
camInterface.prototype.onGotWindow= function () {
if (gPRoot['msens'].getValue()!=0) {
document.multisensor.msens=gPRoot['msens'].getValue();
document.multisensor.mseq= gPRoot['mseq' ].getValue();
document.multisensor.mmod= gPRoot['mmod' ].getValue();
document.multisensor.msel= gPRoot['msel' ].getValue();
}
document.getElementById("idFileSize").innerHTML="<b>"+(Math.round(gPRoot['FRAME_SIZE'].getValue()/1024))+"K</b>";
document.getElementById("idActualWidth").innerHTML="<b>"+gPRoot['ACTUAL_WIDTH'].getValue()+"</b>";
document.getElementById("idActualHeight").innerHTML="<b>"+gPRoot['ACTUAL_HEIGHT'].getValue()+"</b>";
document.getElementById("idInfoWidth").innerHTML=gPRoot['ACTUAL_WIDTH'].getValue();
document.getElementById("idInfoHeight").innerHTML=gPRoot['ACTUAL_HEIGHT'].getValue();
///NOTE: gets here with undefined frAmeselGetOuter ???
frAmeselSetOuterScaled ("idMagnifier_frAmesel",{w:gPRoot['ACTUAL_WIDTH'].getValue(),h:gPRoot['ACTUAL_HEIGHT'].getValue()});
//document.title+="<"+document.actualWidth+":"+frAmeselGetOuter("idAexp_frAmesel").toSource()+":"+frAmeselGetInner ("idAexp_frAmesel").toSource()+"/";
frAmeselSetOuterScaled ("idAexp_frAmesel",{w:gPRoot['ACTUAL_WIDTH'].getValue(),h:gPRoot['ACTUAL_HEIGHT'].getValue()});
//document.title+=frAmeselGetInner ("idAexp_frAmesel").toSource()+">";
document.dcm.dh= gPRoot['dh'].getValue();
document.dcm.dv= gPRoot['dv'].getValue();
document.dcm.bh= gPRoot['bv'].getValue();
document.dcm.bv= gPRoot['bh'].getValue();
//TODO: allow to switch window and resolution simultaneously, so the result image size stays the same?
document.receivedGeometry.w=gPRoot['ww'].getValue();
document.receivedGeometry.h=gPRoot['wh'].getValue();
document.receivedGeometry.dh=document.dcm.dh;
document.receivedGeometry.dv=document.dcm.dv;
document.flipX= gPRoot['fliph'].getValue(); ///Was missing - did it have some reason?
document.flipY= gPRoot['flipv'].getValue(); ///Was missing - did it have some reason?
setBuTtonState("idFlipHor_CB",document.flipX?1:0);
setBuTtonState("idFlipVert_CB",document.flipY?1:0);
document.receivedGeometry.flipX=document.flipX;
document.receivedGeometry.flipY=document.flipY;
var i;
var n=-1;
for (i=0; i< document.getElementById("idImageSize").options.length; i++) {
if (document.getElementById("idImageSize").options[i].value==(gPRoot['ww'].getValue()+"x"+gPRoot['wh'].getValue())){
n=i;
document.getElementById("idImageSize").options[i].selected=true;
} else document.getElementById("idImageSize").options[i].selected=false;
}
if (n<0) {
if ((gPRoot['ww'].getValue()==gPRoot['SENSOR_WIDTH'].getValue()) && (gPRoot['wh'].getValue()==gPRoot['SENSOR_HEIGHT'].getValue())) document.getElementById("idImageSize").options[1].selected=true;
else document.getElementById("idImageSize").options[0].selected=true;
}
// move it back to when image is acquired if the resize frame will not "behave well" - don't agree to the mouse
//alert ("onGotWindow\ngPRoot['SENSOR_WIDTH'].getValue()="+gPRoot['SENSOR_WIDTH'].getValue()+"\ngPRoot['SENSOR_HEIGHT'].getValue()="+gPRoot['SENSOR_HEIGHT'].getValue()+"\ngPRoot['ww'].getValue()="+gPRoot['ww'].getValue()+"\ngPRoot['wh'].getValue()="+gPRoot['wh'].getValue()+"\ngPRoot['wl'].getValue()="+gPRoot['wl'].getValue()+"\ngPRoot['wt'].getValue()="+gPRoot['wt'].getValue());
//document.title+=" ##"+gPRoot['SENSOR_WIDTH'].getValue()+":"+gPRoot['SENSOR_HEIGHT'].getValue()+" ";
frAmeselSetOuter ("idWindow_frAmesel",{w:gPRoot['SENSOR_WIDTH'].getValue(),h:gPRoot['SENSOR_HEIGHT'].getValue()});
//+=" $$"+gPRoot['ww'].getValue()+":"+gPRoot['wh'].getValue()+" "+gPRoot['wl'].getValue()+":"+gPRoot['wt'].getValue()+" ";
frAmeselSetInner ("idWindow_frAmesel",{w:gPRoot['ww'].getValue(),h:gPRoot['wh'].getValue(),l:gPRoot['wl'].getValue(),t:gPRoot['wt'].getValue()});
showDCMBin ("idDCMhor", document.decimationXMask,document.dcm.dh);
showDCMBin ("idDCMvert",document.decimationYMask,document.dcm.dv);
showDCMBin ("idBINhor", document.binningXMask,document.dcm.bh);
showDCMBin ("idBINvert",document.binningYMask,document.dcm.bv);
if (gPRoot['msens'].getValue()!=0) showMulti ("idMultiSensor",document.multisensor.mmod,document.multisensor.mseq,document.multisensor.msel);
}
/*
document.multisensor.msens=gPRoot['msens'].getValue();
document.multisensor.mseq= gPRoot['mseq' ].getValue();
document.multisensor.mmod= gPRoot['mmod' ].getValue();
document.multisensor.msel= gPRoot['msel' ].getValue();
*/
camInterface.prototype.onGotGains= function () {
setSliderAndText("gainRed_slIder", gPRoot['gr'].getValue());
setSliderAndText("gainGreen_slIder",gPRoot['gg'].getValue());
setSliderAndText("gainBlue_slIder", gPRoot['gb'].getValue());
};
camInterface.prototype.onGotGammaPxl= function () {
setSliderAndText("blackLev_slIder", gPRoot['pxl'].getValue());
setSliderAndText("gamma_slIder", gPRoot['gam'].getValue());
//alert("g-<"+gPRoot['gam'].getValue());
//document.title+="g-<"+gPRoot['gam'].getValue()+" ";
};
camInterface.prototype.onGotScales= function () {
setSliderAndText("gainRed2Green_slIder", gPRoot['rscale'].getValue());
setSliderAndText("gainBlue2Green_slIder",gPRoot['bscale'].getValue());
/// setSliderAndText("gainGreen2Green_slIder",gPRoot['gscale'].getValue());///NOTE: does not exist yet
};
camInterface.prototype.onGotWbScales= function () {
//alert ("onGotWbScales: "+gPRoot['wbrs'].getValue()+"/"+gPRoot['wbbs'].getValue());
setSliderAndText("autoRed2Green_slIder", gPRoot['wbrs'].getValue());
setSliderAndText("autoBlue2Green_slIder",gPRoot['wbbs'].getValue());
/// setSliderAndText("gainGreen2Green_slIder",gPRoot['wbgs'].getValue());///NOTE: does not exist yet
};
camInterface.prototype.onGotWbEn= function () {
showAWB();
// if (gPRoot['wben'].getValue())
updateFields();
};
camInterface.prototype.onGotBit= function () {
document.bit= gPRoot['bit'].getValue();
///nothing to do here - just disable images?
};
camInterface.prototype.onGotColor= function () {
document.getElementById('idColorSelect').value=gPRoot['color'].getValue();
};
camInterface.prototype.onGotQuality= function () {
setSliderAndText("Quality_slIder", gPRoot['iq'].getValue());
};
camInterface.prototype.onGotExposure= function () {
setSliderAndText("exposure_slIder",gPRoot['e'].getValue());
};
camInterface.prototype.onGotSaturation= function () {
var sat_blue= gPRoot['csb'].getValue();
var sat_red= gPRoot['csr'].getValue();
if (sat_red<0) sat_red=0;
if (sat_blue<0) sat_blue=0;
if (sat_red>5) sat_red=5;
if (sat_blue>5) sat_blue=5;
var sat=sat_red; if (sat_blue > sat) sat= sat_blue;
setSliderAndText("colorSat_slIder",sat);
setSliderAndText("colorDiffSat_slIder",(sat_blue > sat_red) ? (1-(sat_red/sat_blue)): ((sat_blue/sat_red)-1));
};
camInterface.prototype.onHistWnd= function () {
var aw=gPRoot['ACTUAL_WIDTH'].getValue();
var ah=gPRoot['ACTUAL_HEIGHT'].getValue();
var hw=Math.round (aw*gPRoot['hrw'].getValue());
var hh=Math.round (ah*gPRoot['hrh'].getValue());
frAmeselSetOuter ("idAexp_frAmesel",{w:aw,h:ah});
frAmeselSetInner ("idAexp_frAmesel",{w:hw, h:hh,
l:Math.round ((aw-hw)*gPRoot['hrl'].getValue()),
t:Math.round ((ah-hh)*gPRoot['hrt'].getValue())});
}
camInterface.prototype.onAexp= function () {
setSliderAndText("idAexpLevels_slIder",gPRoot['ael'].getValue()*256);
setSliderAndText("idAexpPercents_slIder",gPRoot['aef'].getValue()*100);
}
camInterface.prototype.onAexpMaxExp= function () {
document.getElementById("idAEMax").value=Math.round(1000*parseFloat(gPRoot['aemax'].getValue()));
}
camInterface.prototype.onAexpOnOff= function () {
showAutoexp();
}
camInterface.prototype.onGotHistOutG=function (val) {
document.AePercentsToDisplay=100*val;
showAutoexp(); // already done/will be?
}
camInterface.prototype.onFTPOnOff=function() {
// alert ("gPRoot['ftp'].getValue()="+gPRoot['ftp'].getValue());
setBuTtonState("idConfWebENABLE_CB", (gPRoot['ftp'].getValue()=="on") ? 1 : 0);
}
function onConfWebENABLE() {
//alert (getBuTton('idConfWebENABLE_CB').toSource());
gPRoot['ftp'].setValue((getBuTton('idConfWebENABLE_CB').s=='1')?'on':'off');
// var win=window.open('/autocampars.php','Ssave/Restore parameters','scrollbars=no,resizable=yes,toolbar=no,location=no,directories=no,menubar=no,status=no' );
var win=window.open('/autocampars.php','Ssave/Restore parameters','' );
if (win) {
win.focus();
}
}
function muxHistLevel() {
var ret= (gPRoot['ae'].getValue()=='on')?
(parseFloat(getSliderValue("idAexpMonitor_slIder"))/256):
gPRoot['ael'].getValue();
if (!isNaN(ret)) return ret;
forceSliderAndText("idAexpMonitor_slIder", document.AeLevelToDisplayDefault);
return document.AeLevelToDisplayDefault;
}
function onChangeAexpSliders(n) {
if (n==0) { /// idAexpLevels"
gPRoot['ael'].setValue(parseFloat(getSliderValue("idAexpLevels_slIder"))/256);
// document.title+="["+parseFloat(getSliderValue("idAexpLevels_slIder"))+"]";
} else if (n==1) { ///idAexpPercents
gPRoot['aef'].setValue(parseFloat(getSliderValue("idAexpPercents_slIder"))/100);
} else if (n==2) {
}
setAEParameters();
}
function onDoubleClickAexpSliders(n) {
var aexp_on= (gPRoot['ae'].getValue()=='on');
if (n==0) {
document.AeLevelToControl=document.AeLevelToControlDefault;
forceSliderAndText("idAexpLevels_slIder", document.AeLevelToControl);
//document.title+="("+document.AeLevelToControl+")";
} else if (n==1) {
if (aexp_on) forceSliderAndText("idAexpPercents_slIder", document.AePercentsToControlDefault);
} else if (n==2) forceSliderAndText("idAexpMonitor_slIder", document.AeLevelToDisplayDefault); // add at startup?
// setAEParameters(); // send to camera
}
function toggleAexp(){ // from other toggle controls (double click on exposure slider, click on brightness icon near exposure slider)
setBuTtonState("idAexpOn_CB", !getBuTton("idAexpOn_CB").s);
setAexp(getBuTton("idAexpOn_CB").s!=0);
}
function setAexp(state){ // form Autoexposure checkbox
var aexp_on= (gPRoot['ae'].getValue()=='on');
gPRoot['ae'].setValue(state? "on":"off");
showAutoexp();
setAEParameters(); // send to camera
}
function showAutoexp(){ // received from camera, it already set document.xxxx values according to received XML data
var aexp_on= (gPRoot['ae'].getValue()=='on');
setBuTtonState("idAexpOn_CB", aexp_on); // make sure there is no race between user and camera. Can it be avoided?
enableSlider("exposure_slIder", !aexp_on); // manual only
enableSlider("idAexpLevels_slIder", 1); // always
enableSlider("idAexpPercents_slIder", aexp_on); // auto only
enableSlider("idAexpMonitor_slIder", aexp_on); // auto only
document.getElementById("idAexpInfoPercentsValue").innerHTML=Math.round(100*document.AePercentsToDisplay)/100;
document.getElementById("idAexpInfoLevelsValue").innerHTML=Math.round(
((gPRoot['ae'].getValue()=='on')?(parseFloat(getSliderValue("idAexpMonitor_slIder"))):(256*gPRoot['ael'].getValue()))
);
if (!aexp_on) setSliderAndText("idAexpPercents_slIder", document.AePercentsToDisplay);
}
camInterface.prototype.initHistControls= function () {
// alert ("missing gInterface.initHistControls()");
// setBuTtonState("idEnableHist_CB",document.hist.enabled);
setBuTtonState("idHistColorsR", document.hist.r);
setBuTtonState("idHistColorsG", document.hist.g);
setBuTtonState("idHistColorsB", document.hist.b);
setBuTtonState("idHistColorsW", document.hist.w);
setBuTtonState("idHistColorsG1",document.hist.g1);
setBuTtonState("idHistColorsG2",document.hist.g2);
if (document.hist.sqr) clickBuTton("idHistSqrt");
else clickBuTton("idHistLin");
if (document.hist.stl==0) clickBuTton("idHistStyleDots");
else if (document.hist.stl==1) clickBuTton("idHistStyleLine");
else if (document.hist.stl==2) clickBuTton("idHistStyleFilled");
if (document.hist.stl==0) clickBuTton("idHistInterpGaps");
else if (document.hist.stl==1) clickBuTton("idHistInterpSteps");
else if (document.hist.stl==2) clickBuTton("idHistInterpLin");
document.getElementById("idHistScale_TX").value=document.hist.scale;
document.getElementById("idHistAver_TX").value=document.hist.aver;
document.getElementById("idHistHeight_TX").value=document.hist.hght;
};
//function ccs_makeHistURL() {
camInterface.prototype.makeHistURL= function () {
gRequests.histUrl=gRequests.histogram;
gRequests.histUrl+="sqrt="+(document.hist.sqr?"1":"0")+"&";
var sc=parseFloat(document.getElementById("idHistScale_TX").value);
if (!((sc>0.001) && (sc< 1000))) {
sc=1.0
document.getElementById("idHistScale_TX").value=sc;
document.hist.scale=sc;
}
gRequests.histUrl+="scale="+(5/sc)+"&";
var av=parseInt(document.getElementById("idHistAver_TX").value);
if (!((av>=0) && (av< 256))) {
av=5;
document.getElementById("idHistAver_TX").value=av;
document.hist.aver=av;
}
gRequests.histUrl+="average="+av+"&";
var hh=parseInt(document.getElementById("idHistHeight_TX").value);
if (!((hh>0) && (hh<=256))) {
hh=128;
document.getElementById("idHistHeight_TX").value=hh;
document.hist.hght=hh;
}
gRequests.histUrl+="height="+hh+"&";
if (hh != parseInt(document.getElementById("idDivHist").style.height)) {
document.getElementById("idDivHist").style.height=hh;
document.getElementById("imgHistogram").height=hh;
showWindow(); // show with new histogram height
}
gRequests.histUrl+="fillz="+ ((document.hist.interp==1)?"1":"0")+"&";
gRequests.histUrl+="linterpz="+((document.hist.interp==2)?"1":"0")+"&";
gRequests.histUrl+="draw="+ (document.hist.stl ^ (document.hist.stl? 3 : 0))+"&"; //0->0, 1->2, 2->1
var colors=(document.hist.r? 1 : 0) +
(document.hist.g1? 2 : 0) +
(document.hist.g2? 4 : 0) +
(document.hist.b? 8 : 0) +
(document.hist.w? 16 : 0) +
(document.hist.g? 32 : 0);
gRequests.histUrl+="colors="+colors;
// document.title=document.ccs.hist.url;
}
// read streamer parameters
/*
//TODO: Add to ccam.php? TODO:
with (document.streamStat) {
var nam= getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_name' )[0]);
var multicast= (getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_multicast' )[0])=="true")?1:0;
var destport= parseInt(getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_dest_port' )[0]));
var ipstack= (getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_ip_stack' )[0])=="true")?1:0;
var circbuf= (getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_circbuf' )[0])=="true")?1:0;
var mmap= (getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_mmap' )[0])=="true")?1:0;
var fps= parseInt(getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_fps' )[0]));
var maxfps= parseInt(getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_maxfps' )[0]));
var verbose= (getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_verbosy' )[0])=="true")?1:0;
var n= parseInt(getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_n' )[0]));
var autostart= (getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_autostart' )[0])=="true")?1:0;
var destip= getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_dest_ip' )[0]);
var stream= parseInt(getIfDefinedFCNV(XML_req.responseXML.getElementsByTagName('S_STREAM' )[0]));
document.streamerIsRunning=stream;
showStreamerRunning();
document.cameraStrParametersAcquired=1;
changeStreamPars();
} //with (document.streamStat)
document.cameraParametersAcquired=1;
dbgp(4," Srw");
//alert ("ccs_rcv_rstat_rw - 1028");
}
*/
camInterface.prototype.gotHistogram=function() {
// document.requests.hist--; debugComm(8192);
// alert ("gotHistogram:typeof(this)="+typeof(this)+"\ntypeof(gRequests)="+typeof(gRequests));
gRequests.inProgress= false;
//document.title+='R';
document.getElementById("imgHistogram").src=gRequests.bgHist.src;
requestsNextState(true); // **** back to the main loop: GOOD
}
camInterface.prototype.gotShadow=function() {
// alert ("gotShadow: typeof(this)="+typeof(this)+"\ntypeof(gRequests)="+typeof(gRequests));
if ((gPRoot["comp_run"].getValue() != 'run') && (gRequests.shadowImage.src.indexOf(gRequests.circbuf_fp)>=0)) {
gRequests.ExifCircbufImgNeeded=false;
}
gRequests.inProgress= false;
document.imageGot= true;
document.getElementById("idCameraImage").src=gRequests.shadowImage.src;
document.getElementById("idImageLink").href= gRequests.shadowImage.src;
// frAmeselSetImage ("idMagnifier_frAmesel", gRequests.shadowImage.src);
/// copy to navigator
/// restore it here if the resize frame will not "behave well" - don't agree to the mouse
// frAmeselSetImage ("idWindow_frAmesel",gRequests.shadowImage.src);
if ((gRequests.lastImageWidth != gPRoot['ACTUAL_WIDTH'].getValue()) ||
(gRequests.lastImageHeight != gPRoot['ACTUAL_HEIGHT'].getValue())) {
var ix=parseInt(document.getElementById("DIV_ALL").style.width);
var iy=parseInt(document.getElementById("DIV_ALL").style.height);
if (!controlsOverlap()) ix-=document.controlsWidth;
// now ix*iy what can be used for an image - no, iy may be more than wanted. But for now - stay with it.
gRequests.lastImageWidth= gPRoot['ACTUAL_WIDTH'].getValue();
gRequests.lastImageHeight=gPRoot['ACTUAL_HEIGHT'].getValue();
if (ix > (iy*gRequests.lastImageWidth/gRequests.lastImageHeight))
ix= (iy*gRequests.lastImageWidth/gRequests.lastImageHeight);
else iy =(ix*gRequests.lastImageHeight/gRequests.lastImageWidth);
ix=Math.round(ix);
iy=Math.round(iy);
//document.title+=" ##"+ix+":"+iy+" ";
document.getElementById("idDivCameraImage").style.width=ix;
document.getElementById("idDivCameraImage").style.height=iy;
// resizeMainWindow();
showWindow();
dbgp(4," Inew");
} else {
dbgp(4," Iold");
}
frAmeselSetImage ("idMagnifier_frAmesel", gRequests.shadowImage.src);
frAmeselSetImage ("idWindow_frAmesel",gRequests.shadowImage.src);
requestsNextState(true); // **** back to the main loop: GOOD
}
camInterface.prototype.statusUpdate=function() {
//document.title+=" ##1:"+gRequests.inProgress+" ";
var t=new Date();
if (gRequests.inProgress) {
document.getElementById("idCommStat_Free").style.display="none";
document.getElementById("idCommStat_Waiting").style.display="";
document.getElementById("idCommStat_None").style.display="none";
document.getElementById("idCommStatRequest_active").style.display="";
if (gRequests.state == COMM_STATE_INIT) document.getElementById("idCommStat_Command").style.display=""; ///chnage to "Init"
else document.getElementById("idCommStat_Command").style.display="none";
if (gRequests.state == COMM_STATE_CMD) document.getElementById("idCommStat_Status").style.display=""; ///command/status
else document.getElementById("idCommStat_Status").style.display="none";
if (gRequests.state == COMM_STATE_IMG) document.getElementById("idCommStat_Image").style.display="";
else document.getElementById("idCommStat_Image").style.display="none";
if (gRequests.state == COMM_STATE_HIST) document.getElementById("idCommStat_Histogram").style.display="";
else document.getElementById("idCommStat_Histogram").style.display="none";
///obsolete
/*
document.getElementById("idCommStat_AECommand").style.display="none";
document.getElementById("idCommStat_AEStatus").style.display="none";
document.getElementById("idCommStat_StrCommand").style.display="none";
document.getElementById("idCommStat_StrStatus").style.display="none";
*/
document.getElementById("idCommStatTimePassed").innerHTML=""+(Math.round((t.getTime()-gRequests.lastRequestSent)/1000))
} else {
document.getElementById("idCommStat_Free").style.display="";
document.getElementById("idCommStat_Waiting").style.display="none";
document.getElementById("idCommStat_None").style.display="";
document.getElementById("idCommStatRequest_active").style.display="none";
// sometimes when the program is starting, cursor remains in "wait" state for some time. try to reset it additionally
document.body.style.cursor=document.contextHelpOn?"help":"";
}
}
/// Removing all nonstop, nostreamer
/// Setting all parameters together - TODO: separate them
// lets risk and try them as streamer-ok
function toggleAWB() {
gPRoot['wben'].setValue(gPRoot['wben'].getValue()?0:1);
showAWB();
// alert (gPRoot['wben'].getValue());
}
function showAWB() {
var whiteBalanceEnabed= gPRoot['wben'].getValue();
enableSlider("gainRed2Green_slIder",!whiteBalanceEnabed);
enableSlider("gainBlue2Green_slIder",!whiteBalanceEnabed);
enableSlider("gainRed_slIder",!whiteBalanceEnabed);
enableSlider("gainBlue_slIder",!whiteBalanceEnabed);
document.divVisibility["idDivWB"]=whiteBalanceEnabed? "" : "none";
// document.getElementById("idDivWB").style.display = document.divVisibility["idDivColors"];
showWindow();
}
function toggleGainScale() {
if (document.getElementById("gainRed").style.display == "none") {
document.getElementById("gainRed").style.display = "";
document.getElementById("gainBlue").style.display = "";
document.getElementById("gainRed2Green").style.display = "none";
document.getElementById("gainBlue2Green").style.display = "none";
} else {
document.getElementById("gainRed").style.display = "none";
document.getElementById("gainBlue").style.display = "none";
document.getElementById("gainRed2Green").style.display = "";
document.getElementById("gainBlue2Green").style.display = "";
}
}
function updateQuality() {
gPRoot['iq'].setValue(parseInt(getSliderValue('Quality_slIder')));
}
function updateColor() {
gPRoot['color'].setValue(parseInt(document.getElementById('idColorSelect').value));
}
function updateFlipX() {
gPRoot['fliph'].setValue((getBuTton('idFlipHor_CB').s!=0)?1:0);
}
function updateFlipY() {
gPRoot['flipv'].setValue((getBuTton('idFlipVert_CB').s!=0)?1:0);
}
function updateGammaBlack() {
//alert("g->"+getSliderValue('gamma_slIder'));
gPRoot['gam'].setValue(parseFloat(getSliderValue('gamma_slIder')));
gPRoot['pxl'].setValue(parseFloat(getSliderValue('blackLev_slIder')));
//document.title+="g->"+getSliderValue('gamma_slIder')+" ";
}
//updateBlackLev()
function updateExposure() {
if (!(gPRoot['ae'].getValue()=='on')) {
gPRoot['e'].setValue(parseFloat(getSliderValue("exposure_slIder")));
}
}
function updateAnalogGains() {
var gg=parseFloat(getSliderValue("gainGreen_slIder"));
gPRoot['gg'].setValue(gg);
// gPRoot['ggb'].setValue(gg);
if (!gPRoot['wben'].getValue()) { /// No update in the auto white balance mode!
gPRoot['gr'].setValue(parseFloat(getSliderValue("gainRed_slIder")));
gPRoot['ggb'].setValue(parseFloat(getSliderValue("gainGreen_slIder")));
gPRoot['gb'].setValue(parseFloat(getSliderValue("gainBlue_slIder")));
}
}
function updateSaturation() {
var csat= parseFloat(getSliderValue("colorSat_slIder"));
var dsat= parseFloat(getSliderValue("colorDiffSat_slIder"));
var sat_red= csat*((dsat>0)? (1-dsat): 1);
var sat_blue= csat*((dsat>0)? 1: (1+dsat));
gPRoot['csb'].setValue(sat_blue);
gPRoot['csr'].setValue(sat_red);
}
function updateScales() {
if (!gPRoot['wben'].getValue()) { /// No update in the auto white balance mode!
gPRoot['rscale'].setValue(parseFloat(getSliderValue("gainRed2Green_slIder")));
gPRoot['bscale'].setValue(parseFloat(getSliderValue("gainBlue2Green_slIder")));
gPRoot['gscale'].setValue(1.0);
}
}
function updateWbScales() {
gPRoot['wbrs'].setValue(parseFloat(getSliderValue("autoRed2Green_slIder")));
gPRoot['wbbs'].setValue(parseFloat(getSliderValue("autoBlue2Green_slIder")));
gPRoot['wbgs'].setValue(1.0);
}
function updateWOI() {
var wnd=frAmeselGetInner ("idWindow_frAmesel");
// adjust window size (after decimation, actual) to multiple of 16x16 pixels
if (!((document.dcm.dh>=1) && (document.dcm.dh<=16))) document.dcm.dh=1;
if (!((document.dcm.dv>=1) && (document.dcm.dv<=16))) document.dcm.dv=1;
wnd.w=document.dcm.dh*16*Math.round(wnd.w/document.dcm.dh/16);
wnd.h=document.dcm.dv*16*Math.round(wnd.h/document.dcm.dv/16);
gPRoot['ww'].setValue(wnd.w);
gPRoot['wh'].setValue(wnd.h);
gPRoot['wl'].setValue(wnd.l);
gPRoot['wt'].setValue(wnd.t);
gPRoot['dh'].setValue(document.dcm.dh);
gPRoot['dv'].setValue(document.dcm.dv);
gPRoot['bh'].setValue((document.dcm.bh)?document.dcm.bh:0);
gPRoot['bv'].setValue((document.dcm.bv)?document.dcm.bv:0);
document.dcm.dhs=document.dcm.dh;
document.dcm.dvs=document.dcm.dv;
document.dcm.bhs=document.dcm.bh;
document.dcm.bvs=document.dcm.bv;
if (document.multisensor.msens) {
//document.title="updateWOI(),document.multisensor.mseq="+document.multisensor.mseq+" gPRoot['mseq'].getValue="+gPRoot['mseq'].getValue ();
//document.title+=" mmod="+document.multisensor.mmod+" gPRoot['mmod'].getValue="+gPRoot['mmod'].getValue ();
//document.title+=" msel="+document.multisensor.msel+" gPRoot['msel'].getValue="+gPRoot['msel'].getValue ();
gPRoot['mseq'].setValue(document.multisensor.mseq);
gPRoot['mmod'].setValue(document.multisensor.mmod);
gPRoot['msel'].setValue(document.multisensor.msel);
}
}
function setDefaultGain(n) { // n =0..2 (gainGR/gainR2G/gainB2G), m=-1,0,+1 (dec, set, inc)
// if (n==0) document.getElementById("idGainG").value = 4.0; // medium mvalue
// else if (n==1) document.getElementById("idGainR2G").value =1.0;
// else if (n==2) document.getElementById("idGainB2G").value =1.0;
if (n==0) {gPRoot['gg'].setValue(4.0); forceSliderAndText("gainGreen_slIder", 4.0); }
else if (n==1) {gPRoot['rscale'].setValue(1.0); forceSliderAndText ("gainRed2Green_slIder", 1.0);}
else if (n==2) {gPRoot['bscale'].setValue(1.0);forceSliderAndText("gainBlue2Green_slIder",1.0);}
else if (n==3) {gPRoot['wbrs'].setValue(1.0);forceSliderAndText("autoRed2Green_slIder",1.0);}
else if (n==4) {gPRoot['wbbs'].setValue(1.0); forceSliderAndText("autoBlue2Green_slIder",1.0);}
else if (n==5) forceSliderAndText("gainRed_slIder",parseFloat(getSliderValue("gainGreen_slIder")));
else if (n==6) forceSliderAndText("gainBlue_slIder",parseFloat(getSliderValue("gainGreen_slIder")));
updateAnalogGains();
}
function setSat(m) { // Color Saturation m=0 (set) -1 (dec sat), +1 (inc sat), -2 (dec blue, inc red), +2 (inc blue, dec red)
// if (m==0) document.getElementById("idTextSat").value = 2.0
// else if (m==3) document.getElementById("idTextDiffSat").value = 0;
if (m==0) forceSliderAndText("colorSat_slIder", 2.0);
else if (m==3) forceSliderAndText("colorDiffSat_slIder", 0);
// updateSaturation();
}
function setG(m){ // Gamma m=-1,0,+1 (dec, set, inc)
// document.getElementById("idGamma").value=0.5;
forceSliderAndText("gamma_slIder",0.5);
//updateGammaBlack();
}
// sets variables from text fields, tnen - again sliders and links
function updateFields() { // is it needed?
updateQuality();
updateColor();
updateFlipX();
updateFlipY();
updateGammaBlack();
updateExposure();
updateAnalogGains();
updateSaturation();
updateScales();
updateWbScales();
updateWOI();
}
function setInfoFPS() {
var k= document.sensorFPS * getSliderValue("exposure_slIder");
if (document.fpslim && (document.sensorFPS > (0.99 * document.userFps))) {
document.getElementById("idSpanFPS").style.color="blue";
} else if (k>990) {
document.getElementById("idSpanFPS").style.color="red";
} else {
document.getElementById("idSpanFPS").style.color="green";
}
}
function updateFromSizeSelector(id) {
var i;
var ww, wh;
var wnd=frAmeselGetInner ("idWindow_frAmesel");
// document.title="$$w="+wnd.w +" h="+wnd.h+" l="+wnd.l +" t="+wnd.t;
if (document.getElementById(id).value == "full window") {
ww=gPRoot['SENSOR_WIDTH'].getValue();
wh=gPRoot['SENSOR_HEIGHT'].getValue();
} else {
i=document.getElementById(id).value.indexOf("x");
if (i>0){
ww=parseInt(document.getElementById(id).value);
wh=parseInt(document.getElementById(id).value.substr(i+1));
}
}
var diff= (wnd.w!=ww) || (wnd.h!=wh);
// document.title+=" ww="+ww+" wh="+wh;
wnd.l+=Math.round((wnd.w-ww)/2);
wnd.t+=Math.round((wnd.h-wh)/2);
wnd.w=ww;
wnd.h=wh;
if (wnd.l<0) wnd.l=0;
if (wnd.l>(gPRoot['SENSOR_WIDTH'].getValue()-wnd.w)) wnd.l= gPRoot['SENSOR_WIDTH'].getValue()-wnd.w;
if (wnd.t<0) wnd.t=0;
if (wnd.t>(gPRoot['SENSOR_HEIGHT'].getValue()-wnd.h)) wnd.t= gPRoot['SENSOR_HEIGHT'].getValue()-wnd.h;
// document.title+="w="+wnd.w +" h="+wnd.h+" l="+wnd.l +" t="+wnd.t;
frAmeselSetInner ("idWindow_frAmesel",wnd);
// alert ("ww="+ww+" wh="+wh+" diff="+diff);
if (diff) updateWOI();///TODO: only update what is needed
}
function setAEMax() {
gPRoot['aemax'].setValue(0.001*parseInt(document.getElementById("idAEMax").value));
}
function setAEParameters() {
updateHistWnd();
}
function updateHistWnd() { /// send histogram window to teh camera
var wnd=frAmeselGetInner ("idAexp_frAmesel");
var aw=gPRoot['ACTUAL_WIDTH'].getValue();
var ah=gPRoot['ACTUAL_HEIGHT'].getValue();
gPRoot['hrw'].setValue(wnd.w/aw);
gPRoot['hrh'].setValue(wnd.h/ah);
gPRoot['hrl'].setValue((wnd.w>=aw)?0.5:(wnd.l/(aw-wnd.w)));
gPRoot['hrt'].setValue((wnd.h>=ah)?0.5:(wnd.t/(ah-wnd.h)));
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
*! -----------------------------------------------------------------------------**
*! FILE NAME : camvc_video.js
*! DESCRIPTION: Provides interface to a video plugin
*! Copyright (C) 2008 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camvc_video.js,v $
*! Revision 1.5 2011/05/30 00:10:29 elphel
*! Fixed embedding gecko-mediaplayer. Thanks, Kevin!
*!
*! Revision 1.4 2010/02/26 17:04:23 dzhimiev
*! 1. corrected a couple of typos
*!
*! Revision 1.3 2009/10/07 23:08:02 elphel
*! removed alert box on stream end (now reports in title bar only)
*!
*! Revision 1.2 2008/12/14 05:37:58 elphel
*! Fixed resizing of the window when video plugin is running
*!
*! Revision 1.1 2008/12/13 23:38:18 elphel
*! split camvc2.html, - now only HTML code is in camvc2.html, all the javascript in in camvc_main.js, camvc_video.js and other files that were already separate
*!
*!
*/
document.videoSaved={viewer:1,image:1}; // save user selected values if changed by other conditions;
document.idVideoNIndex=-1;
document.idVideoNameIndex=-1;
document.videoMime="";
// document.getElementById("idVideoR").innerHTML="L"+document.getElementById("idVideoObject").run;
// document.getElementById("idVideoObject").run=1;
function streamerChangedByUser() {
var n,i;
startStopStreamV(0);// stop streamer if it was running
for (i=0; i<document.getElementById("idVideoName_TX").options.length; i++) {
if (document.getElementById("idVideoName_TX").options[i].selected) n=i+1;
}
// change idVideoN too.
for (i=0; (i<document.configsData.length) && (document.idVideoNIndex<0); i++) {// first time - find index, later - just use stored
if (document.configsData[i].id=="idVideoN") document.idVideoNIndex=i;
}
document.getElementById("idVideoN_TX").value=n;
inputInChange(document.idVideoNIndex,null); // simulate that control change (will be hidden from user)
showStreamerParams();
if ((document.getElementById(document.TABS_video.id).style.display != "none") &&
(getSelectedTab(document.TABS_video.id)==document.TABS_video.n)){
// alert ("streamerChangedByUser:"+document.TABS_video.id+"/"+document.TABS_video.n);
onClickTabs(document.TABS_video.id,document.TABS_video.n); // show it if the height changed
}
}
function streamerNumberRead() {
var n,i;
for (i=0; (i<document.configsData.length) && (document.idVideoNameIndex<0); i++) {// first time - find index, later - just use stored
if (document.configsData[i].id=="idVideoName") document.idVideoNameIndex=i;
}
n=parseInt(document.getElementById("idVideoN_TX").value)-1; // starting from 0
for (i=0; i<document.getElementById(document.configsData[document.idVideoNameIndex].id+"_TX").options.length; i++) {
document.getElementById(document.configsData[document.idVideoNameIndex].id+"_TX").options[i].selected = (i==n);
}
inputInChange(document.idVideoNameIndex,null); // simulate that control change (will be hidden from user)
showStreamerParams();
if ((document.getElementById(document.TABS_video.id).style.display != "none") &&
(getSelectedTab(document.TABS_video.id)==document.TABS_video.n)){
// alert ("streamerNumberRead:"+document.TABS_video.id+"/"+document.TABS_video.n);
onClickTabs(document.TABS_video.id,document.TABS_video.n); // show it if the height changed
}
}
function showStreamerParams() {
var n = document.getElementById("idVideoN_TX").value; // should be string
var i;
for (i=0; i<document.configsData.length;i++) {
if (typeof(document.configsData[i].sp) != "undefined") {
document.getElementById(document.configsData[i].id+"All").style.display=(document.configsData[i].sp.indexOf(n)>=0)?"":"none";
}
}
}
function startStopStreamV(turnOn) { // true - on, false off
if (!turnOn) hideStreamPage(); /// is it needed?
// startStopStream(turnOn);
}
function clickedVideoRun() {
var m=(getBuTton("idVideoRun_CB").s!=0);
startStopStreamV(m);
}
function showStreamerRunning(){
setBuTtonState("idVideoRun_CB",document.streamerIsRunning);
}
function streamerChangedState (n) { // 0 - stopped. called when streamer state is first acquired (initialy and after start/stop
showVideoMode();
}
/// When display mode is selectd in the UI
function changeStillVideo(vns){ //change here to be able to disable completely (0 - none, 1 - still, 2 - video)
if ((document.videoMime=="") && (vns>1)) vns=1;
document.videoSaved.viewer=(vns==2);
document.videoSaved.image= (vns==1);
showVideoMode();
}
///Still does not work form start - trying to turn video when compressor is off causes "non", not "still"
function showVideoMode() {
// will add indication what display mode is now active
if((document.videoSaved.viewer != 0) &&
document.cameraParametersAcquired && // when the image size is known to create correct window
(document.getElementById("idVideoViewer_outer").style.display == "none")) {
if (gPRoot["comp_run"].getValue() == 'run') {
makeStreamPage();
} else {
hideStreamPage();
}
// document.getElementById("idShieldControlsFromPlugin").style.display="block"; /// may be done once
} else
if(document.videoSaved.viewer == 0) {
if(document.getElementById("idVideoViewer_outer").style.display != "none") {
hideStreamPage();
// document.getElementById("idShieldControlsFromPlugin").style.display="none"; /// may be done once
} else
if(document.videoSaved.image) {
document.getElementById("idDivCameraImage").style.display = "";
showWindow();
}
if(!document.videoSaved.image) {
document.getElementById("idDivCameraImage").style.display = "none";
showWindow();
}
}
}
// ----- Video viewer plugin functions ------
/*
document.videoSaved={viewer:1,image:1}; // save user selected values if changed by other conditions;
*/
function destroyStreamPage() {
hideStreamPage();
document.getElementById("idVideoViewer").innerHTML = "";
}
function hideStreamPage() {
document.getElementById("idShieldControlsFromPlugin").style.display="none"; /// may be done once
// if (document.getElementById("idEmbeddedVideo") && (typeof(document.getElementById("idEmbeddedVideo").Stop)!=undefined))
if (document.getElementById("idEmbeddedVideo") && (typeof(document.getElementById("idEmbeddedVideo").Stop)!='undefined'))
document.getElementById("idEmbeddedVideo").Stop();
document.getElementById("idVideoR").style.display = "none"; // letter "R" in playback mode
// document.getElementById("idVideoViewer").innerHTML = "";
document.getElementById("idVideoViewer_outer").style.display = "none";
if(document.videoSaved.image) {
document.getElementById("idDivCameraImage").style.display = "";
setBuTtonState("btnDisplayStill",1);
setBuTtonState("btnDisplayNone",0);
// clickBuTton("btnDisplayStill"); /// duplicate?
showWindow();
} else {
setBuTtonState("btnDisplayStill",0);
setBuTtonState("btnDisplayNone",1);
// clickBuTton("btnDisplayNone");
}
setBuTtonState("btnDisplayVideo",0);
// if ( document.videoSaved.viewer) clickBuTton("btnDisplayVideo");
// else clickBuTton("btnDisplayStill");
}
// will compare current pluging window size and change lowres if needed (rebuilding plugin)
// will check only the horizontal dimension of the window, not the vertical
function checkStreamPageSize(w, h) { // will possibly destroy and rebuild video viewer with new "lowres" parameter
if(document.getElementById("idVideoViewer_outer").style.display == "none")
return false; // just in case - we suppose player is running
var lr = 0;
if(gPRoot['ACTUAL_WIDTH'].getValue() > w) lr = 1;
if(gPRoot['ACTUAL_WIDTH'].getValue() > 2 * w) lr = 2; // enough ?
if(gPRoot['ACTUAL_WIDTH'].getValue() > 4 * w) lr = 3;
if(document.lowres != lr) {
document.lowres = lr;
document.getElementById("idVideoViewer").innerHTML = "";
makeStreamRes();
return true;
}
return false;
}
///TODO: Make "stop" if turning streamer off (or other
function makeStreamPage() {
if(document.videoMime == "")
return; // will not be used
var availableWidth = parseInt(document.getElementById("DIV_ALL").style.width) - (controlsOverlap() ? 0 : document.controlsWidth);
document.lowres = 0;
if(gPRoot['ACTUAL_WIDTH'].getValue() > availableWidth) document.lowres = 1;
if(gPRoot['ACTUAL_WIDTH'].getValue() > 2 * availableWidth) document.lowres = 2; // enough ?
if(gPRoot['ACTUAL_WIDTH'].getValue() > 4 * availableWidth) document.lowres = 3;
makeStreamRes();
document.videoSaved.image = (document.getElementById("idDivCameraImage").style.display != 'none'); // to be able to restore user selection
// document.getElementById("idDivCameraImage").style.display = 'none'; // hide it - no need to hide, video will anyway be on top
showWindow(); // recalculate/redisplay
//debugWindowShow( document.getElementById("idVideoViewer_outer").innerHTML);
//debugWindowShow( document.body.innerHTML);
}
/// originally video output was not scaled - only used lowres.
/// Now it will be regular scaling
function makeStreamRes() {
var availableWidth = parseInt(document.getElementById("DIV_ALL").style.width) - (controlsOverlap() ? 0 : document.controlsWidth);
document.getElementById("idVideoR").style.display = ""; // letter "R/P/L"
document.getElementById("idVideoR").innerHTML = "L"; // letter "R/P/L"
if(document.videoMime == "")
return; // will not be used
// var w = (document.actualWidth >> document.lowres);
// var h = (document.actualHeight >> document.lowres);
var w = availableWidth;
var h = availableWidth*gPRoot['ACTUAL_HEIGHT'].getValue()/gPRoot['ACTUAL_WIDTH'].getValue();
document.getElementById("idVideoViewer").style.width = w;
document.getElementById("idVideoViewer").style.height = h;
document.getElementById("idVideoViewer_outer").style.display = "";
// var fps = document.ccs.sensorFPS;
/*
var fps = document.sensorFPS;
if(!((fps > 0) && (fps < 10000)))
fps = 0;
*/
//!FIXME 8.0
/*
with(document.ccs.strstat) {
var target = "";
if(document.videoMime == "application/x-elphel-ogm") {
target = " href='" + ((multicast && (mp > 0)) ? ("rtp://" + mip + ":" + mp) : ("rtsp://" + ip + ":" + p)) + "'";
} else {
target = " data='" + "rtsp://" + ip + "/'";
}
*/
/// tempoarary - get host ip/name from gRequests.imgsrv
var ip=gRequests.imgsrv.substr(7,gRequests.imgsrv.length-13);
var port="554";
document.getElementById("idShieldControlsFromPlugin").style.display="none";
// was a typo: kength
// if (!(document.getElementById("idVideoViewer").innerHTML.kength>0)) document.getElementById("idVideoViewer").innerHTML =
if (document.getElementById("idVideoViewer").innerHTML.length>0) document.getElementById("idVideoViewer").innerHTML =
'<embed '+
'style="z-index:-1;background-color: #6666aa;" '+
// 'style="z-index:-1;background-color: #6666aa;'+
// 'width:'+Math.round(w)+'px;height:'+Math.round(h)+'px;" '+
'id="idEmbeddedVideo" '+
'nocache="1" '+
'showlogo="0" '+
'type="application/x-mplayer2" '+
'onMediaComplete="videoOnMediaComplete();" '+
'onEndOfStream="videoOnEndOfStream();" '+
'onVisible="videoOnVisible();" '+
'onVisible="videoOnVisible();" '+
'onHidden="videoOnHidden();" '+
'onMouseDown="videoOnMouseDown();" '+
'showcontrols="0" '+
'autostart="1" '+
'vo="xv" '+
'framedrop="1" '+
'src="rtsp://'+ip+':'+port+'"'+
' width="'+w+'" height="'+Math.round(h)+'"'+ //Oleg
'/>';
/*
'onDestroy="videoOnDestroy();" '+ // does not work - already not defined?
"<object type=" + document.videoMime +
// " href='" + ((multicast && (mp > 0)) ? ("rtp://" + mip + ":" + mp) : ("rtsp://" + ip + ":" + p)) + "/'" +
// " href='" + ((multicast && (mp > 0)) ? ("rtp://" + mip + ":" + mp) : ("rtsp://" + ip + ":" + p)) + "'" +
// " data='" + "rtsp://" + ip + "/'" +
target +
" width=" + w +
" height=" + h +
" lowres=" + document.lowres +
" fps=" + fps +
" onrun= 'onStreamViewerRun();'" +
monitorFrameSkip() +
" id='idVideoObject'></object>\n";
*/
}
function resizeVideo (w,h) {
if (document.getElementById('idEmbeddedVideo') && (document.getElementById('idEmbeddedVideo').width>0)) {
document.title+= "set:"+w+":"+h+" ";
document.getElementById("idEmbeddedVideo").width=w;
document.getElementById("idEmbeddedVideo").height=h;
document.getElementById("idVideoViewer").style.width=w+"px";
document.getElementById("idVideoViewer").style.height=h+"px";
}
}
function getSizeVideo () {
if (document.getElementById('idEmbeddedVideo') && (document.getElementById('idEmbeddedVideo').width>0)) {
document.title+= "got:"+parseInt(document.getElementById("idEmbeddedVideo").width)+":"+parseInt(document.getElementById("idEmbeddedVideo").height)+" ";
return {width: parseInt(document.getElementById("idEmbeddedVideo").width),
height:parseInt(document.getElementById("idEmbeddedVideo").height)};
} else {
document.title+= "got: nothing";
return {width:0,height:0};
}
}
//function videoOnEndOfStream() {alert ("videoOnEndOfStream");onVideoStateChange('videoOnEndOfStream');}
function videoOnEndOfStream() {document.title="*** videoOnEndOfStream ***";}
//function videoOnMediaComplete() {alert ("videoOnMediaComplete");onVideoStateChange('videoOnMediaComplete');}
function videoOnMediaComplete() {onVideoStateChange('videoOnMediaComplete');}
//function videoOnVisible() {onVideoStateChange('videoOnVisible');}
function videoOnVisible() {
return;
if (document.getElementById("idShieldControlsFromPlugin").style.display=="none") {
document.getElementById("idShieldControlsFromPlugin").style.display="block"; /// may be done once
// alert ( document.getElementById("idVideoViewer").innerHTML);
}
onVideoStateChange('videoOnVisible');
}
function videoOnHidden() {onVideoStateChange('onHidden');}
function videoOnDestroy() {onVideoStateChange('onDestroy');}
function onVideoStateChange(ev) {
document.title="**ev="+ev+" play="+document.getElementById("idEmbeddedVideo").playState;
if (!document.getElementById("idEmbeddedVideo").isplaying()) hideStreamPage();
}
function videoOnMouseDown(){
// var wasHidden=document.getElementById("idShieldControlsFromPlugin").style.display=="none";
document.getElementById("idShieldControlsFromPlugin").style.display=(document.getElementById("idShieldControlsFromPlugin").style.display=="none")?"block":"none";
// document.title=wasHidden?"controls hidden":"controls visible";
}
/* obsolete */
function onStreamViewerRun(){
//alert("onStreamViewerRun")
if(document.getElementById("idVideoObject") != null)
if(!(parseInt(document.getElementById("idVideoObject").run) == 1))
document.getElementById("idVideoObject").run = 1;
/*
var t=new Date();
document.title+= " "+ document.getElementById("idVideoObject").run+"("+t.getTime()+")";
alert(document.getElementById("idVideoObject").run+"("+t.getTime()+")");
*/
}
//document.ccs.sensorFPS
function makeStreamPlayback(vw,vh,url) {
//alert("makeStreamPlayback")
if(document.videoMime == "")
return; // will not be used
var availableWidth = parseInt(document.getElementById("DIV_ALL").style.width) - (controlsOverlap() ? 0 : document.controlsWidth);
document.playbacklowres = 0;
if(vw > availableWidth)
document.playbacklowres = 1;
if(vw > 2 * availableWidth)
document.playbacklowres = 2; // enough ?
if(vw > 4 * availableWidth)
document.playbacklowres = 3;
makeStreamPlaybackRes(vw, vh, url);
document.videoSaved.image = (document.getElementById("idDivCameraImage").style.display != 'none'); // to be able to restore user selection
/// document.getElementById("idDivCameraImage").style.display = 'none'; // hide it - leave it (under video)
showWindow(); // recalculate/redisplay
}
function monitorFrameSkip() {
var fskip = parseInt(document.getElementById("idFPSReduce_TX").value) - 1;
if(!((fskip >= 0) && (fskip < 10)))
fskip = 0;
document.getElementById("idFPSReduce_TX").value = fskip + 1;
return fskip ? (" frameskip=" + fskip) : "";
}
function fpsReduceChanged() {
//TODO: will add restarting of either video (Live or Play)
}
function makeStreamPlaybackRes(vw,vh,url) {
if (document.videoMime=="") return; // will not be used
var w=(vw >> document.playbacklowres);
var h=(vh >> document.playbacklowres);
document.getElementById("idVideoViewer").style.width = w;
document.getElementById("idVideoViewer").style.height =h;
document.getElementById("idVideoViewer_outer").style.display="";
document.getElementById("idVideoViewer").innerHTML =
"<object type="+document.videoMime+
// " href='"+ url+"/'"+
" href='"+ url+"'"+
" width="+w+
" height="+h+
" lowres="+document.lowres+
" onframe='onPlayerFrame();'"+
" onrun= 'onPlayerRun();'"+
monitorFrameSkip()+
" id='idVideoObject'></object>\n";
//alert ( document.getElementById("idVideoViewer").innerHTML);
document.getElementById("idVideoR").style.display="";
document.getElementById("idVideoR").innerHTML="R";
// document.getElementById("idVideoRunButtons").style.top=h;
document.getElementById("VideoRun_slIder").style.width=w-125;
document.getElementById("idVideoRunButtonsPlayback").style.display="";
// createVideoSlider(w-200,document.sessions.session[document.DVR_fileNum.ses].files.file[document.DVR_fileNum.fil].dur);
// createVideoSlider(w-225,document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].files.file[document.videoFiles[document.DVR_fileNum.n].f].dur);
createVideoSlider(w-225,document.sessions.session[document.videoFiles[document.DVR_fileNum.n].s].files.file[document.videoFiles[document.DVR_fileNum.n].f].frames);
//
document.getElementById("idVideoRunButtonsLive").style.display="none";
// debugWindowShow(document.getElementById("idVideoRunButtons").innerHTML);
}
function stopStreamPlayback() {
//alert("stopStreamPlayback");
document.getElementById("idVideoR").style.display = "none";
document.getElementById("idVideoViewer").innerHTML = "";
document.getElementById("idVideoViewer_outer").style.display = "none";
showVideoMode(); // will show from camera - video or still
}
function onPlayerFrame() {
var v, s;
var t = new Date();
t = t.getTime();
if(t > (document.playbackUpdated + document.playbackUpdateInterval)) {
document.playbackUpdated = t;
document.playbackUpdateInterval = parseInt(document.getElementById("idDVRSliderDelay_TX").value);
v = document.getElementById("idVideoObject").frame;
v = v.substr(v.indexOf("/") + 1);
while(v.substr(0, 1) == " ")
v = v.substr(1);
v = v.substr(0, v.indexOf(" "));
if(showPlaybackPosition(v))
setSliderAndText("VideoRun_slIder", parseInt(v)); // only once a second
}
}
function createVideoSlider(slen,dur) { // now dur - in frames
createSlider ("VideoRun_slIder", //should end with "_slIder"
0, // there will be a image button to the left of the slider
"", //supports switching between *.* and *_press.* (fixed some problems in original code
13, // width of the slider pointer
"images/slider_ball_13x25.png?_TIMESTAMP_", // url of the pointer image
slen, // length of a slider itself (the rest will be used for input text field
"images/slider_rail_left13x25.png?_TIMESTAMP_", // left end of rail image (should be same width as pointer_width)
"images/slider_rail_right13x25.png?_TIMESTAMP_", // right end of rail image (should be same width as pointer_width)
"images/slider_rail_1x25.png?_TIMESTAMP_", // may be 1 pixel wide - will be streched as needed
"images/empty.png?_TIMESTAMP_", //document.slIdersArray[i].dummyImageUrl, // 1x1 pixel transparent image to fill empty div (maybe will remove it)
5, // standard "size" attribute of the text input
5, // standard "maxlen" attribute of the text input
"text-align:right; font-size: 12px; color:blue; ", // style to be applied to text input field
// "sec", // to be written after the input window (i.e. "sec", "mph", etc)
"frm", // to be written after the input window (i.e. "sec", "mph", etc)
"", // style to be applied to the units field (above)
0, // minimal value in the text field, corresponds to the leftmost slider position
dur, // maximal value in the text field, corresponds to the rightmost slider position
0, // 0 - linear, 1 - logarithmic scale for the slider
// 1, // number of decimals after the point in the text field
0, // number of decimals after the point in the text field
"50", // percents of the slider height used for fine control - positive - top, negative - bottom
// in the following actions id is defined as the outer DIV id. so "alert(id)" as the value will work
"", // action to be "eval()" when slider is moved. id is defined as the outer DIV id
"", // action when text field is changed or slider button released
"", // action when (right) button is pressed
"");//action on slider double click (i.e. auto on/off)
setSliderAndText("VideoRun_slIder", 0);
enableSlider("VideoRun_slIder", 0);
// debugWindowShow(document.getElementById("idVideoViewer_outer").innerHTML);
}
function shieldButtons(l,h) {
//document.title="shieldButtons("+l+","+h+")";
var i;
if(l < 0) {
for(i = 0; i < 250; i += 25)
document.getElementById("idShieldButtonsFromPlugin_" + i).style.height = 25 + "px";
// document.getElementById("idShieldButtonsFromPlugin").style.display="none";
// document.getElementById("idShieldButtonsFromPlugin").style.height=25+"px";
// document.getElementById("idShieldButtonsFromPlugin").style.left=0+"px";
// document.getElementById("idShieldButtonsFromPlugin").style.width=256+"px";
} else {
document.getElementById("idShieldButtonsFromPlugin_" + l).style.height = h + "px";
// document.getElementById("idShieldButtonsFromPlugin").style.display="";
// document.getElementById("idShieldButtonsFromPlugin").style.height=(h)+"px";
// document.getElementById("idShieldButtonsFromPlugin").style.left=l+"px";
// document.getElementById("idShieldButtonsFromPlugin").style.width=25+"px";
// document.getElementById("idShieldButtonsFromPlugin").style.top="0px";
}
}
function initShieldButtons() {
// alert ("function initShieldButtons()");
var i;
for(i = 0; i < 250; i += 25){
document.getElementById("idShieldButtonsFromPlugin_" + i).style.height = 25 + "px";
document.getElementById("idShieldButtonsFromPlugin_" + i).style.width = 25 + "px";
document.getElementById("idShieldButtonsFromPlugin_" + i).style.left =i + "px";
document.getElementById("idShieldButtonsFromPlugin_" + i).style.top = 0 + "px";
document.getElementById("idShieldButtonsFromPlugin_" + i).style.display = "block";
}
}
function initVideoPlugin() {
document.videoMime= detectPlugin();
document.getElementById("btnDisplayVideo").style.display=(document.videoMime!="")?"":"none";
if (document.videoMime=="") document.videoSaved.viewer=0;
}
function detectPlugin() {
var pluginmime = "";
// var pluginmimes = ['application/x-elphel-ogm', 'video/mjpeg', 'video/mpeg'];
var pluginmimes = ['application/x-mplayer2','application/x-elphel-mjpeg', 'application/x-elphel-ogm'];
// var pluginmimes = ['application/x-elphel-mjpeg'];
var i, mmime;
//alert (navigator.mimeTypes.length);
//alert (navigator.mimeTypes.namedItem('application/x-mplayer2'));// object mimeType
//alert ("description="+navigator.mimeTypes.namedItem('application/x-mplayer2').description);
//alert ("type="+navigator.mimeTypes.namedItem('application/x-mplayer2').type);
for(i = 0; i < pluginmimes.length; i++) {
mmime = navigator.mimeTypes[pluginmimes[i]];
if((mmime != null) && (mmime.enabledPlugin)) {
if(mmime.enabledPlugin)
genresfound = (mmime.enabledPlugin.name.toLowerCase().indexOf("genres") >= 0);
pluginmime = (genresfound || pluginmime == "" ? pluginmimes[i] : pluginmime);
if(genresfound) {
//alert(pluginmime);
return pluginmime;
}
}
}
return pluginmime;
}
// end of video plugin
function setInitialVideoModeButtons() {
document.getElementById("idVideoRunButtonsPlayback").style.display = "none";
document.getElementById("idVideoRunButtonsLive").style.display = "";
///FIXME: Tempoorary hide recorder control buttons
document.getElementById("idVideoRunButtons").style.display = "none";
/* if ( document.videoSaved.viewer) clickBuTton("btnDisplayVideo");
else clickBuTton("btnDisplayStill");
*/
clickBuTton("btnDisplayStill");
}
<html>
<head>
<title>Close me</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body onLoad="window.close();">
<h1>You may safely close this page </h1>
</body>
</html>
/*
*! -----------------------------------------------------------------------------**
*! elphelButtons.js
*!
*! Copyright (C) 2006-2007 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: elphelButtons2.js,v $
*! Revision 1.4 2008/12/11 06:37:57 elphel
*! Added animated refresh button
*!
*! Revision 1.3 2008/12/10 22:07:12 elphel
*! Made all buttons but drop-down to treat mouseout as mouseup (so if the toggle button was pressed and that caused the screen to redraw that caused the button to slide out of the mouse - that will count as mouse pressed and released)
*!
*! Revision 1.2 2008/12/09 16:29:54 elphel
*! Added event.preventDefault() here and there. Really helped - with the current FF buttons were dragged away like images (before I could only fight it using background images, not the regular ones)
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.1 2008/04/24 18:18:12 elphel
*! 2-state regular button upgraded to 3-state one - with optional disabled state
*!
*! Revision 1.1.1.1 2007/09/19 04:51:17 elphel
*! This is a fresh tree based on elphel353-2.10
*!
*! Revision 1.2 2007/09/19 04:51:17 elphel
*! Upgraded license (header)
*!
*!
*/
/*
function createButton (id, // id of DIV tag to make a button of
widthHeight, // {w:xxx, h:yyy} - if empty will use the ones specified in DIV in HTML code
imageURL, // URL of the image file name. Should consist of equal size images of the (WxH - see widthHeight)
// with the each column corresponding to one button, rows - different button states
// alternative - array of array of styles (outer - for numbers, inner - for states
// CSS buttons will use imageURL+"_"+n+"_"+s as class name for number/state
buttonNum, // number of button column in imageURL (starting from 0)
buttonType, // "" - just a single static image, no changes
// "b" - regular button with two states - released (row 0) and pressed (row 1)
// - removed- "tN" (N - number, may be empty) - toggle between N ( "t", "t1" parsed as "t2") states on each mouseDown
// "TN" (N - number, may be empty) - toggle between N ( "t", "t1" parsed as "t2") states on each mouseUp,
// mousedown just turnes button to next row as "pressed"
// - removed- "dN" - drop-down of N buttons, no pressed state. With the long press the whole column is displayed,
// the one on which the mouse was released stays
// "DN" - drop-down, each button has pressed state in the next column (so button uses 2 column/numbers)
dropdownMask, //string of "0" and "1" showing which button will stay after drop-down released
// if buttonType="", dropdownMask can specify the row of static buttons to make the overall image more compact
actOnPress, // action on press ("alert("id="+id+" state="+state);" will show button id (see first argument) and state for
// toggle/drop-down buttons. Should not use " inside, just '
actOnEarlyRelease, // - after short hold
actOnHold, // - after long hold timer expires (automatic for drop-down)
actOnLateRelease,
actOnDblClick)
// in actions you may use variable "simulated" - it will be true if the button was not really clicked, but rather software "clicked"
function clickBuTton(id) // simulate mouse click (for now - don't care on where to release - anyway no long press)
function setBuTton (id,ns) // .n - number, .s - state (row) - will not change internal number/ actions associated with it
function getBuTton (id) // returns {n:xx, s:yy}
setBuTtonState(id,state)
relies on global:
document.buttonHoldDelay = 500; //1000; // ms to consider button long-pressed
document.doubleclickDelay=300; //ms
*/
if (!document.all){ // normal browsers
document.auto="auto"; // z-index
document.setAttrStyle="style";
document.setAttrClass="class";
} else { // obsolete browsers
document.auto="0";
document.setAttrStyle="cssText"
document.setAttrClass="className";
}
document.buTtonDblclickTimerID=null;
document.buTtonHoldTimerID=null;
document.BuTtonSimulated=false; // not a real key-press but a simulated one,
function createButton (id, // id of DIV tag to make a button of
widthHeight, // {w:xxx, h:yyy} - if empty will use the ones specified in DIV in HTML code
imageURL, // URL of the image file name. Should consist of equal size images of the (WxH - see widthHeight)
// with the each column corresponding to one button, rows - different button states
// alternative - array of array of styles (outer - for numbers, inner - for states
// CSS buttons will use imageURL+"_"+n+"_"+s as class name for number/state
//TODO: - think of a "cover" for the <span> element to prevent selection of the text.
buttonNum, // number of button column in imageURL (starting from 0)
buttonType, // "" - just a single static image, no changes
// "b" - regular button with two states - released (row 0) and pressed (row 1) disabled - row2
// all other states (for animations are considered same as not pressed)
// - removed- "tN" (N - number, may be empty) - toggle between N ( "t", "t1" parsed as "t2") states on each mouseDown
// "TN" (N - number, may be empty) - toggle between N ( "t", "t1" parsed as "t2") states on each mouseUp,
// mousedown just turnes button to next row as "pressed"
// - removed- "dN" - drop-down of N buttons, no pressed state. With the long press the whole column is displayed,
// the one on which the mouse was released stays
// "DN" - drop-down, each button has pressed state in the next column (so button uses 2 column/numbers)
// "R" - radio button, then dropdownMask used to hold ID of the next in chain
dropdownMask, //string of "0" and "1" showing which button will stay after drop-down released
// if buttonType="", dropdownMask can specify the row of static buttons to make the overall image more compact
actOnPress, // action on press ("alert("id="+id+" state="+state);" will show button id (see first argument) and state for
// toggle/drop-down buttons. Should not use " inside, just '
actOnEarlyRelease, // - after short hold
actOnHold, // - after long hold timer expires (automatic for drop-down)
actOnLateRelease, // if "*" - use actOnEarlyRelease
actOnDblClick, // on double click
actAfterRelease) { // after actually released
//document.title="*** "+id+" ***";
if (!document.getElementById(id)) alert ("button container ID="+id+" does not exist");
if (widthHeight.w) document.getElementById(id).style.width=widthHeight.w;
if (widthHeight.h) document.getElementById(id).style.height=widthHeight.h;
if (typeof (imageURL)!="string") {
// alert(imageURL[0][0]);
var i,j;
s="";
for (i=0;i<imageURL.length;i++) for (j=0;j<imageURL[i].length;j++) s+='<input type="hidden" id="'+id+'_' +i+'_'+j+'" value="'+ imageURL[i][j] +'"/>\n';
s+='<input type="hidden" id="'+id+'_n" value="'+ 0 +'"/>\n';
s+='<input type="hidden" id="'+id+'_s" value="'+ 0 +'"/>\n';
document.getElementById(id).innerHTML+=s;
} else {
document.getElementById(id).style.backgroundImage="url("+imageURL+")";
}
var s=0;
if (typeof(buttonType) =="undefined") buttonType="";
if (buttonType) {
buttonTypeMod=buttonType.substr(1);
buttonType=buttonType.substr(0,1);
buttonTypeMod=buttonTypeMod?parseInt(buttonTypeMod):0;
if (typeof(dropdownMask) =="undefined") dropdownMask="";
if (typeof(actOnPress) =="undefined") actOnPress ="";
if (typeof(actOnEarlyRelease)=="undefined") actOnEarlyRelease ="";
if (typeof(actOnHold) =="undefined") actOnHold ="";
if (typeof(actOnLateRelease) =="undefined") actOnLateRelease ="";
if (typeof(actOnDblClick) =="undefined") actOnDblClick ="";
if (typeof(actAfterRelease) =="undefined") actAfterRelease ="";
/*
var ev ='document.getElementById(id).onmousedown= function() {buTtonOnMouseDown("'+id+'","'+buttonNum+'","'+buttonType+'","'+buttonTypeMod+'","'+dropdownMask+'","'+actOnPress+'","'+actOnEarlyRelease+'","'+actOnHold+'","'+actOnLateRelease+'","'+actOnDblClick+'","'+actAfterRelease+'");}';*/
var ev ='document.getElementById(id).onmousedown= function(event) {buTtonOnMouseDown(event,"'+id+'","'+buttonNum+'","'+buttonType+'","'+buttonTypeMod+'","'+dropdownMask+'","'+actOnPress+'","'+actOnEarlyRelease+'","'+actOnHold+'","'+actOnLateRelease+'","'+actOnDblClick+'","'+actAfterRelease+'");}';
//alert(ev);
eval (ev);
document.getElementById(id).onmouseup=function (event) { buTtonOnMouseUp(event);};
// document.getElementById(id).onmouseout=function () { releaseCurrentButton();};
document.getElementById(id).onmouseout=function (event) { outOfCurrentButton(event);};
} else {
if (dropdownMask) s=parseInt(dropdownMask);
}
if (typeof (imageURL)!="string") {
document.getElementById(id).setAttribute(document.setAttrStyle,imageURL[0][0]);
} else {
document.getElementById(id).style.backgroundRepeat="no-repeat";
var l=-parseInt(document.getElementById(id).style.width)*buttonNum;
document.getElementById(id).style.backgroundPosition= (-parseInt(document.getElementById(id).style.width)*buttonNum)+"px "+
(-parseInt(document.getElementById(id).style.height)*s)+"px";
document.getElementById(id).innerHTML="<!"+"-- --"+">";
// Mozilla FF seems not to process "0px 0px" correctly - skipping zero buttons ** update - not just "0px 0px" but any x=y **
}
if (buttonType) document.getElementById(id).style.cursor="pointer";
}
function outOfCurrentButton(event) {
if (document.buTton) {
switch (document.buTton.buttonType.substr(0,1)) {
case 'D':
releaseCurrentButton(); // do nothing
break;
default: buTtonOnMouseUp(event); // same as mouse up?
}
}
}
function releaseCurrentButton() { //just release if it stuck - no action
if (document.buTton) {
document.getElementById(document.buTton.id).style.width=document.buTton.w+"px"; // not needed so far
document.getElementById(document.buTton.id).style.height=document.buTton.h+"px"; // close drop-down if any
setBuTton (document.buTton.id,document.buTton); // has extra members, but that's OK
if (document.buTton.actAfterRelease) eval (document.buTton.actAfterRelease);
document.buTton=null;
}
}
function buTtonDblclickTimerExpired(){
clearTimeout(document.buTtonDblclickTimerID);
document.buTtonDblclickTimerID=null;
}
function buTtonHoldTimerExpired() {
clearTimeout(document.buTtonHoldTimerID);
document.buTtonHoldTimerID=null;
if (!document.buTton) return;
if (document.buTton.buttonType == "D") {
setBuTton (document.buTton.id,{n:document.buTton.n+1,s:0});
document.getElementById(document.buTton.id).style.height=(document.buTton.h * document.buTton.buttonTypeMod)+"px"; // close drop-down if any
// open drop-down buttons
}
var id=document.buTton.id;
var ns ={n:document.buTton.n,s:document.buTton.s};
var simulated= document.buTton.simulated;
if (document.buTton.actOnHold) eval (document.buTton.actOnHold);
}
function buTtonOnMouseUp(e) {
if (!document.buTton) return; // just in case. Needed for releasing disabled button?
if (document.debug & 8) document.title+="buTtonOnMouseUp t="+document.buTton.buttonType;
var late= true;
if (document.buTtonHoldTimerID) {
clearTimeout(document.buTtonHoldTimerID);
document.buTtonHoldTimerID=null;
late=false;
}
var ns ={n:document.buTton.n,s:document.buTton.s};
if (document.buTton.buttonType == "D") {
if (!e) {
var e = window.event;
e.pageX=event.clientX;
e.pageY=event.clientY;
}
var offsetTrail =document.getElementById(document.buTton.id);
var absY0 = 0;
while (offsetTrail){
absY0 += parseInt(offsetTrail.offsetTop);
offsetTrail = offsetTrail.offsetParent;
}
if ((navigator.userAgent.indexOf('Mac') != -1) && typeof(document.body.leftMargin) != 'undefined') {
absY0 += parseInt(document.body.topMargin);
}
document.buTton.s=Math.floor((e.pageY-absY0)/document.buTton.h);
ns.s=document.buTton.s;
while ((document.buTton.s>0) && (document.buTton.dropdownMask.substr(document.buTton.s,1)=="0")) document.buTton.s--;
} else if ((document.buTton.buttonType == "T") || (document.buTton.buttonType == "R")) {
document.buTton.s= getBuTton (document.buTton.id).s;
ns.s=document.buTton.s;
}
var id=document.buTton.id;
var simulated= document.buTton.simulated;
if ( late && document.buTton.actOnLateRelease && (document.buTton.actOnLateRelease!="*")) eval (document.buTton.actOnLateRelease);
if (((!late) || (document.buTton.actOnLateRelease=="*")) && document.buTton.actOnEarlyRelease) eval (document.buTton.actOnEarlyRelease);
// var aar=document.buTton.actAfterRelease;
releaseCurrentButton();
// if (aar) eval (aar);
}
function clickBuTton(id) { // simulate mouse click (for now - don't care on where to release - anyway no long press)
document.getElementById(id).onmousedown();
document.getElementById(id).onmouseup({pageX:0,pageY:0});
document.BuTtonSimulated=true;
}
function buTtonOnMouseDown(e,id,buttonNum,buttonType,buttonTypeMod,dropdownMask,actOnPress,actOnEarlyRelease,actOnHold,
actOnLateRelease,actOnDblClick,actAfterRelease) {
if (typeof(e)!="undefined") e.preventDefault();
if (document.debug & 8) document.title+="."+id+".";
if ((buttonType=="R") && (document.buTton)) {
if (id!=document.buTton.id) {
setBuTton (id,{n:buttonNum,s:0});
document.getElementById(dropdownMask).onmousedown();
}
document.buTton=null;
return;
}
var ns=getBuTton(id); // to be able to use in actOnPress;
if ((buttonType=="b") && (ns.s == 2)) {
return; // state==2 -> disabled
}
if (document.buTton) {
ns=getBuTton(document.buTton.id); // to be able to use in actOnPress;
releaseCurrentButton();
}
var doubleclick=(document.buTtonDblclickTimerID != null);
if (document.buTtonDblclickTimerID) {
clearTimeout(document.buTtonDblclickTimerID);
document.buTtonDblclickTimerID=null;
}
if (document.buTtonHoldTimerID) {
clearTimeout(document.buTtonHoldTimerID);
document.buTtonHoldTimerID=null;
}
if (doubleclick && actOnDblClick) {
var simulated= document.buTton.simulated;
eval (actOnDblClick);
return; // and do nothing more
}
document.buTtonDblclickTimerID = self.setTimeout("buTtonDblclickTimerExpired();", document.doubleclickDelay);
document.buTtonHoldTimerID = self.setTimeout("buTtonHoldTimerExpired();", document.buttonHoldDelay);
document.buTton={id:id,
simulated:document.BuTtonSimulated,
buttonNum:buttonNum,
buttonType:buttonType,
buttonTypeMod: (buttonTypeMod<1)?1:buttonTypeMod,
dropdownMask:dropdownMask,
actOnPress:actOnPress,
actOnEarlyRelease:actOnEarlyRelease,
actOnHold:actOnHold,
actOnLateRelease:actOnLateRelease,
actOnDblClick:actOnDblClick,
actAfterRelease:actAfterRelease,
w:parseInt(document.getElementById(id).style.width),
h:parseInt(document.getElementById(id).style.height),
// ns match the current button state when it was pressed
n:0,s:0
};
if (document.getElementById(id+"_n")) {
document.buTton.n=parseInt(document.getElementById(id+"_n").value);
document.buTton.s=parseInt(document.getElementById(id+"_s").value);
} else {
document.buTton.n=-parseInt(document.getElementById(id).style.backgroundPosition.split(" ")[0])/parseInt(document.getElementById(id).style.width);
document.buTton.s=-parseInt(document.getElementById(id).style.backgroundPosition.split(" ")[1])/parseInt(document.getElementById(id).style.height);
}
if (document.buTton.buttonType == "R") {
setBuTton (id,{n:document.buTton.n,s:1});
// release all the chain
document.getElementById(dropdownMask).onmousedown();
} else if (document.buTton.buttonType == "b") {
setBuTton (id,{n:document.buTton.n,s:document.buTton.s+1});
} else if (document.buTton.buttonType == "D") {
setBuTton (id,{n:document.buTton.n+1,s:document.buTton.s});
} else if (document.buTton.buttonType == "T") {
setBuTton (id,{n:document.buTton.n+1,s:((document.buTton.s==(document.buTton.buttonTypeMod-1))?0:document.buTton.s+1)});
} else {
alert ("Unknown button type="+document.buTton.t);
}
var simulated= document.BuTtonSimulated; //document.BuTton.simulated may be destroyed by now
if (actOnPress) eval(actOnPress); // may use ns record here
if (document.debug&256) document.title+=">"+id+"<";
document.BuTtonSimulated=false;
}
function setBuTtonState(id,state) {
if (!document.getElementById(id)) alert ("setBuTtonState: No button id="+id+" to setBuTtonState");
if (document.getElementById(id+"_n")) {
document.getElementById(id+"_s").value=state;
document.getElementById(id).setAttribute(document.setAttrStyle, document.getElementById(id+"_"+parseInt(document.getElementById(id+"_n").value)+"_"+state).value);
} else {
document.getElementById(id).style.backgroundPosition= parseInt(document.getElementById(id).style.backgroundPosition.split(" ")[0])+"px "+
(-parseInt(document.getElementById(id).style.height)*state)+"px";
}
}
function setBuTton (id,ns) { // .n - number, .s - state (row) - will not change internal number/ actions associated with it
if (document.getElementById(id+"_n")) {
document.getElementById(id+"_n").value=ns.n;
document.getElementById(id+"_s").value=ns.s;
document.getElementById(id).setAttribute(document.setAttrStyle,document.getElementById(id+"_"+ns.n+"_"+ns.s).value);
} else {
document.getElementById(id).style.backgroundPosition= (-parseInt(document.getElementById(id).style.width)*ns.n)+"px "+
(-parseInt(document.getElementById(id).style.height)*ns.s)+"px";
}
}
function getBuTton (id) {
if (!document.getElementById(id)) alert ("getBuTton: No button id="+id);
if (document.getElementById(id+"_n")) {
return {n:parseInt(document.getElementById(id+"_n").value),
s:parseInt(document.getElementById(id+"_s").value)};
} else {
return {n:-parseInt(document.getElementById(id).style.backgroundPosition.split(" ")[0])/parseInt(document.getElementById(id).style.width),
s:-parseInt(document.getElementById(id).style.backgroundPosition.split(" ")[1])/parseInt(document.getElementById(id).style.height)};
}
}
/*
*! -----------------------------------------------------------------------------**
*! elphelContextHelp.js
*!
*! Copyright (C) 2006-2007 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! elphelContextHelp.js
*!
*/
// tooltips
/*
document.debugHelp=true; // will show ID trace until the content help is reached
*/
function createTooltips (id,
w, // size of a rounding element (corner will be twice bigger)
url, // for all the images (0/25/75/100%)
color, // will be used for semitransparent colors (0/25/75/100%) (currently "fffdd00"
color_prefix, // currently "images/bg_" ->images/bg_fffdd0_25.png
maxwidth) { // width can be limited by the outer bow size, but this is the maximum it will go if the outer box is big
var pw=parseInt(document.getElementById(id).style.width);
if (!(pw>(4*w))) {
pw=4*w;
document.getElementById(id).style.width=pw+"px";
}
var w2=2*w;
var mw=pw-2*w2;
var s= '<div id="'+id+'_maskb" style="position: fixed;"><!'+'-- --'+'></div>\n'+
'<div id="'+id+'_maskc" style="position: fixed;"><!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_nw" style="position: absolute; left:0;top:0;width:'+(w2)+';height:'+(w2)+';background-image:url('+url+');"><!'+'-- --'+'></div>\n'+
'<div id="'+id+'_n" style="position: absolute; left:'+(w2)+';top:'+(w)+';width:'+(mw)+';height:'+(w)+';"><!'+'-- --'+'></div>\n'+
'<div id="'+id+'_ne" style="position: absolute; left:'+(pw-w2)+';top:'+(0)+';width:'+(w2)+';height:'+(w2)+';background-image:url('+url+');"><!'+'-- --'+'></div>\n'+
'<div id="'+id+'_w" style="position: absolute; left:'+(w)+';top:'+(w2)+';width:'+(w)+';"><!'+'-- --'+'></div>\n'+
'<div id="'+id+'_body" style="position: absolute; left:'+(w2)+';top:'+(w2)+';width:'+(mw)+';">&nbsp;</div>\n'+
'<div id="'+id+'_e" style="position: absolute; left:'+(pw-w2)+';top:'+(w2)+';width:'+(w)+';"><!'+'-- --'+'></div>\n'+
'<div id="'+id+'_sw" style="position: absolute; left:0;width:'+(w2)+';height:'+(w2)+';background-image:url('+url+');"><!'+'-- --'+'></div>\n'+
'<div id="'+id+'_s" style="position: absolute; left:'+(w2)+';width:'+(mw)+';height:'+(w)+';"><!'+'-- --'+'></div>\n'+
'<div id="'+id+'_se" style="position: absolute; left:'+(pw-w2)+';width:'+(w2)+';height:'+(w2)+';background-image:url('+url+');"><!'+'-- --'+'></div>\n'+
'<input type="hidden" id="'+id+'_bgColor" value="'+ color +'"/>\n'+
'<input type="hidden" id="'+id+'_bgColorPrefix" value="'+ color_prefix +'"/>\n'+
'<input type="hidden" id="'+id+'_transparency" value="-1"/>\n'+
'<input type="hidden" id="'+id+'_corner" value="ne"/>\n'+
'<input type="hidden" id="'+id+'_maxwidth" value="'+maxwidth+'"/>\n';
document.getElementById(id).innerHTML=s;
document.getElementById(id).style.display="none"; // don't show it yet
}
function resizeTooltips(id) { // update dimensions (heights) to accomodate content of the _body
// just in case if the width was changed too
var w2=parseInt(document.getElementById(id+"_nw").style.width);
w=Math.round(w2/2);
var pw=parseInt(document.getElementById(id).style.width);
var mw=pw-2*w2;
document.getElementById(id+"_body").style.width=mw+"px";
document.getElementById(id+"_n").style.width=mw+"px";
document.getElementById(id+"_s").style.width=mw+"px";
// lefts too
document.getElementById(id+"_ne").style.left=(pw-w2)+"px";
document.getElementById(id+"_e").style.left= (pw-w2)+"px";
document.getElementById(id+"_se").style.left=(pw-w2)+"px";
// should be measured after width was changed
var mh=parseInt(document.getElementById(id+"_body").offsetHeight);
document.getElementById(id).style.height=(2*w2+mh)+"px";
document.getElementById(id+"_w").style.height=mh+"px";
document.getElementById(id+"_e").style.height=mh+"px";
document.getElementById(id+"_sw").style.top=(w2+mh)+"px";
document.getElementById(id+"_s").style.top= (w2+mh)+"px";
document.getElementById(id+"_se").style.top=(w2+mh)+"px";
}
function setTooltipsCorner(id,
corner) { // only "nw","ne","se","sw"
// first check if we really need to change anything
if (corner != document.getElementById(id+"_corner").value) {
document.getElementById(id+"_corner").value=corner;
setTooltipsBg(id);
}
}
function setTooltipsTransparency(id,
transp) // only 0/25/50/75/100 are supported
{
transp=25*Math.round(transp/25);
if (transp<0) transp=0;
if (transp>100) transp=100;
if (!((transp>=0) && (transp<=100))) transp=50; // if NaN
// first check if we really need to change anything
if (transp != parseInt(document.getElementById(id+"_transparency").value)) {
document.getElementById(id+"_transparency").value=transp;
setTooltipsBg(id);
}
}
function setTooltipsBg(id) {
var transp=parseInt(document.getElementById(id+"_transparency").value);
var corner = document.getElementById(id+"_corner").value;
var bg_url="url("+document.getElementById(id+"_bgColorPrefix").value+document.getElementById(id+"_bgColor").value+"_"+(100-transp)+".png)";
var bg_col="#"+document.getElementById(id+"_bgColor").value;
if ((transp==0) || (transp==100)) bg_url="";
if (transp!=0) bg_col="";
document.getElementById(id+"_n" ).style.backgroundColor=bg_col;
document.getElementById(id+"_n" ).style.backgroundImage=bg_url;
document.getElementById(id+"_e" ).style.backgroundColor=bg_col;
document.getElementById(id+"_e" ).style.backgroundImage=bg_url;
document.getElementById(id+"_s" ).style.backgroundColor=bg_col;
document.getElementById(id+"_s" ).style.backgroundImage=bg_url;
document.getElementById(id+"_w" ).style.backgroundColor=bg_col;
document.getElementById(id+"_w" ).style.backgroundImage=bg_url;
document.getElementById(id+"_body").style.backgroundImage=bg_url;
document.getElementById(id+"_body").style.backgroundColor=bg_col;
var w2=parseInt(document.getElementById(id+"_nw").style.width);
var shft_right=2*w2;
var shft_down= 2*w2*(transp/25); // top - non-transparent
var nw=(-1 -((corner=="nw")?shft_right:0))+"px "+ (0 -shft_down)+"px";
var ne=(-1 -w2 -((corner=="ne")?shft_right:0))+"px "+ (0 -shft_down)+"px";
var se=(-1 -w2 -((corner=="se")?shft_right:0))+"px "+ (0 -w2 -shft_down)+"px";
var sw=(-1 -((corner=="sw")?shft_right:0))+"px "+ (0 -w2 -shft_down)+"px";
document.getElementById(id+"_nw" ).style.backgroundPosition= nw;
document.getElementById(id+"_ne" ).style.backgroundPosition= ne;
document.getElementById(id+"_se" ).style.backgroundPosition= se;
document.getElementById(id+"_sw" ).style.backgroundPosition= sw;
}
function showTooltipsMask(id) {
// to be able to hover over plugin
var l= parseInt (document.getElementById(id).style.left);
var t= parseInt (document.getElementById(id).style.top);
// var bw=parseInt (document.getElementById(id+"_body").style.width);
// var bh=parseInt (document.getElementById(id+"_body").style.height);
var w2=parseInt(document.getElementById(id+"_nw").style.width);
w=Math.round(w2/2);
var pw=parseInt(document.getElementById(id).style.width);
var ph=parseInt(document.getElementById(id).style.height);
var corner = document.getElementById(id+"_corner").value; // nw,ne/sw/se
document.getElementById(id+"_maskb" ).style.left= l+w+"px";
document.getElementById(id+"_maskb" ).style.top= t+w+"px";
document.getElementById(id+"_maskb" ).style.width= pw-w2+"px";
document.getElementById(id+"_maskb" ).style.height= ph-w2+"px";
document.getElementById(id+"_maskc" ).style.left=
l+parseInt(document.getElementById(id+"_"+corner).style.left)+"px";
document.getElementById(id+"_maskc" ).style.top=
t+parseInt(document.getElementById(id+"_"+corner).style.top)+"px";
document.getElementById(id+"_maskc" ).style.width= w2+"px";
document.getElementById(id+"_maskc" ).style.height=w2+"px";
}
function showTooltipsAt (id, // tooltips outer DIV id
lt, // {l:,t:} where to point (relative to the tooltips DIV parent (DIV_ALL?)
dist) { // distance (x) from the xy to the pointer of the tooltip box
var maxwidth=parseInt(document.getElementById(id+"_maxwidth").value)+dist;
// var w=maxwidth;
//alert ("id="+id);
//alert ("pid="+id);
// let's first see if there is very short message that is one line and does not need the full width.
document.getElementById(id+"_body").style.width=""; // free it
document.getElementById(id).style.width="100%";
// resizeTooltips(id);
//document.title+="**"+document.getElementById(id+"_body").offsetWidth+"/"+document.getElementById(id+"_body").offsetHeight;
var w=parseInt(document.getElementById(id+"_body").offsetWidth)+2*parseInt(document.getElementById(id+"_nw").style.width)+dist;
if (w < maxwidth) maxwidth = w;
else w=maxwidth;
var ow=parseInt(document.getElementById(id).parentNode.style.width);
var oh=parseInt(document.getElementById(id).parentNode.style.height);
var flipX=false;
var flipY=false;
if ((ow-lt.l) < maxwidth) {
flipX=((2*lt.l) > ow);
w=flipX?((lt.l>maxwidth)?maxwidth:lt.l):(ow-lt.l)
}
//now let's set the width and see how high will be the box
w-=dist;
document.getElementById(id).style.width=w+"px";
resizeTooltips(id);
var h=parseInt(document.getElementById(id).style.height)+dist;
if ((oh-lt.t) < h) {
flipY=((2*lt.t) > oh);
}
h-=dist;
document.getElementById(id).style.left= lt.l+(flipX? (-w-dist):(dist))+"px";
document.getElementById(id).style.top= lt.t+(flipY? (-h-dist):(dist))+"px";
var corner=(flipX?(flipY?"se":"ne"):(flipY?"sw":"nw"));
setTooltipsCorner(id,corner);
showTooltipsMask(id); // protect against plugin
}
function setTooltipsText (id, txt) {
document.getElementById(id+"_body").innerHTML=txt;
}
function setTooltipsTextFromId (id, txt_id) {
document.getElementById(id+"_body").innerHTML=document.getElementById(txt_id).innerHTML;
}
//============
// context help will look for invisible DIVs with the same name as the target with prefix "h_" and return the body of that DIV (innerHTML) as the body of the floating window.
// it will traverse the node tree up until some div is found, if document.debugHelp is true, the IDs of the traversed nodes will be displayed too
document.controlTypesList=new Array ("slIder","frAmesel");
function contextHelp(e) {
// if (document.getElementById("DIV_ALL").style.cursor)
if (!e) {
var e = window.event;
e.pageX=event.clientX;
e.pageY=event.clientY;
}
document.shiftKey=e.shiftKey;
var targ;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
var nd=targ;
var nd0id=nd.id;
var txt="";
/*
while (nd && ((!document.getElementById("h_"+nd.id)) || ( document.getElementById("h_"+nd.id).innerHTML.substr(0,1) == "*" ) )) {
if (document.debugHelp) txt+= '<b>'+nd.id+'</b><br/>\n';
if ( document.getElementById("h_"+nd.id).innerHTML.substr(0,1) == "*" ) txt+= document.getElementById("h_"+nd.id).value.substr(1);
nd=nd.parentNode;
}
*/
var ih;
var cont;
while (nd) {
if (document.getElementById("h_"+nd.id)) ih= document.getElementById("h_"+nd.id).innerHTML;
else ih="";
brk=(ih!="") && (ih.substr(0,1)!="*") ;
if (!brk && (ih!="")) ih=ih.substr(1);
if (document.debugHelp) {
if (ih) txt+="<b>"+nd.id+":</b> "+ih;
else txt+="<b>"+nd.id+"</b><br/>\n"
} else txt+=ih;
if (brk) break;
nd=nd.parentNode;
}
// little hack - add help for the Elphel controls if applicable;
var i,j;
for (i=0; i<document.controlTypesList.length;i++) {
if ((nd0id.indexOf(document.controlTypesList[i])>0) && document.getElementById("h_"+document.controlTypesList[i])) {
// make it only accept just ending with a keyword or having "_"
j= nd0id.indexOf(document.controlTypesList[i])+document.controlTypesList[i].length;
if ((nd0id.length==j) || (nd0id.substr(j,1)=="_")) txt+=document.getElementById("h_"+document.controlTypesList[i]).innerHTML;
}
}
setTooltipsText ("idTooltips", txt);
setTooltipsTransparency("idTooltips", getBuTton ("idTranspTooltips_CB").s? controlsTransparency():0);
showTooltipsAt ("idTooltips", {l:e.pageX,t:e.pageY}, 10);
}
//idTranspTooltips_LB
\ No newline at end of file
/*
*! -----------------------------------------------------------------------------**
*! elphelFrames.js
*!
*! Copyright (C) 2006-2007 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: elphelFrames.js,v $
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.2 2008/11/10 19:48:47 elphel
*! blocking text fields updates while they are in focus
*!
*! Revision 1.1.1.1 2007/10/10 20:11:00 elphel
*!
*!
*! Revision 1.1.1.1 2007/09/19 04:51:17 elphel
*! This is a fresh tree based on elphel353-2.10
*!
*! Revision 1.2 2007/09/19 04:51:17 elphel
*! Upgraded license (header)
*!
*!
*/
/*
Function declarations
function createFrameSel (id, // parent element ID (bare div), should have frAmesel in it's name
snap_hw, // shap half width
borderStyle, //
isRelative, // (0 - inner frame has absolute values, 1 - percents of the outer/range)
minWindth,
minHeight,
innerImage, // "" if none (if there will be - provide just empty 1x1)
idWidth, // external text field (or "") to represent (actual) width of the inner frame - onchange will be added automatically
idHeight, // external text field (or "") to represent (actual) height of the inner frame
idLeft,
idTop,
onMove, // call back function to run when frame is moved
onDone, // to run if text filed is changed or the frame mouseup
onDobleClick,
onMouseDown
);
function frAmeselShow (id)
function frAmeselAllTextFromInternal (id);
function frAmeselSetResizeEn (id,en)
function frAmeselGetResizeEn (id)
function frAmeselSetRelative (id,r)
function frAmeselGetRelative (id)
function frAmeselSetOuter (id,wh)
function frAmeselFillParent (id)
function frAmeselGetOuter (id)
function frAmeselSetZindexHandles(id,z)
function frAmeselSetZindexFrame(id,z)
function frAmeselGetZindexHandles(id)
function frAmeselGetZindexFrame(id)
function frAmeselSetInner (id,whlt)
function frAmeselCenterInner (id)
function frAmeselGetInner (id)
function frAmeselSetMagnification (id,m)
function frAmeselGetMagnification (id)
function frAmeselSetSnap (id,m)
function frAmeselGetSnap (id)
function frAmeselSetBorderWidth (id,m)
function frAmeselGetBorderWidth (id)
function frAmeselSetBorderStyle (id,m)
function frAmeselGetBorderStyle (id)
function frAmeselSetImage (id,url)
function frAmeselSetBorderShow (id,showb)
// private functions
function frAmeselOnTextChange(iid,d)
// mouse functions
function frAmeselPressed()
function frAmeselMousedownProcess(e)
function frAmeselMousemoveProcess(e)
function frAmeselMouseupProcess(e)
//call back functions
function frAmeselActOnDone (id)
function frAmeselActOnChange (id)
function frAmeselActOnDoubleclick (id)
*/
function createFrameSel (id, // parent element ID (bare div), should have frAmesel in it's name
frameBorderStyle, // id of an optional div with a frame that will be resized when outer dimentions changed
snap_hw, // shap half width
borderStyle, //
isRelative, // (0 - inner frame has absolute values, 1 - percents of the outer/range)
minWindth,
minHeight,
innerImage, // "" if none (if there will be - provide just empty 1x1)
idWidth, // external text field (or "") to represent (actual) width of the inner frame - onchange will be added automatically
idHeight, // external text field (or "") to represent (actual) height of the inner frame
idLeft,
idTop,
onMove, // call back function to run when frame is moved
onDone, // to run if text filed is changed or the frame mouseup
onDobleClick,
onMouseDown
) {
var s="";
s+= '\n<div id="'+id+'_frameBorder" style="position:absolute;'+ (frameBorderStyle?('border:'+frameBorderStyle+';'):'')+'">\n';
// add outer image and cover protection from dragging (if any)
s+= '\n<div id="'+id+'_frame_root" style="position:absolute; border:'+borderStyle+'">\n';
s+= ' <div id="'+id+'_frame_rootClip" style="position:absolute;">\n';
if (innerImage) {
s+= ' <div id="'+id+'_frame_image" style="position:absolute;">\n'+
' <img id="'+id+'_frame_image_img" src="'+innerImage+'" style="width:100%;height:100%"/>\n'+
' </div>\n';
s+= ' <div id="'+id+'_frame_cover" style="position:absolute;width:100%;height:100%">\n'+
' <!'+'-- --'+'>\n'+
' </div>\n';
} else {
s+= '<!'+'-- --'+'>\n';
}
s+= '</div>\n';
s+= '</div>\n';
s+= '<div id="'+id+'_n" style="position:absolute; cursor:n-resize"> <!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_ne" style="position:absolute; cursor:ne-resize"><!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_e" style="position:absolute; cursor:e-resize"> <!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_se" style="position:absolute; cursor:se-resize"><!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_s" style="position:absolute; cursor:s-resize"> <!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_sw" style="position:absolute; cursor:sw-resize"><!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_w" style="position:absolute; cursor:w-resize"> <!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_nw" style="position:absolute; cursor:nw-resize"><!'+'-- --'+'></div>\n';
s+= '<div id="'+id+'_c" style="position:absolute; cursor:move"> <!'+'-- --'+'></div>\n';
s+= '<input id="'+id+'_snap_hw" type="hidden" style="display:none" value="'+snap_hw+'">\n';
s+= '<input id="'+id+'_relative" type="hidden" style="display:none" value="'+(isRelative?"1":"")+'">\n';
s+= '<input id="'+id+'_minWidth" type="hidden" style="display:none" value="'+minWindth+'">\n';
s+= '<input id="'+id+'_minHeight" type="hidden" style="display:none" value="'+minHeight+'">\n';
s+= '<input id="'+id+'_magnifierScale" type="hidden" style="display:none" value="0">\n';
s+= '<input id="'+id+'_borderWidth" type="hidden" style="display:none" value="0">\n';
s+= '<input id="'+id+'_borderStyle" type="hidden" style="display:none" value="none">\n';
s+= '<input id="'+id+'_realOuterWidth" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_realOuterHeight" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_outerPixelScale" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_realInnerWidth" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_realInnerHeight" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_realInnerLeft" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_realInnerTop" type="hidden" style="display:none" value="1">\n';
// last value set from outside (not to generate "onchange" if the ne value is the same as the old one
s+= '<input id="'+id+'_lastInnerWidth" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_lastInnerHeight" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_lastInnerLeft" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_lastInnerTop" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_text_w" type="hidden" style="display:none" value="'+idWidth+'">\n';
s+= '<input id="'+id+'_text_h" type="hidden" style="display:none" value="'+idHeight+'">\n';
s+= '<input id="'+id+'_text_l" type="hidden" style="display:none" value="'+idLeft+'">\n';
s+= '<input id="'+id+'_text_t" type="hidden" style="display:none" value="'+idTop+'">\n';
// last data written to control (may be float)
s+= '<input id="'+id+'_textld_w" type="hidden" style="display:none" value="0">\n';
s+= '<input id="'+id+'_textld_h" type="hidden" style="display:none" value="0">\n';
s+= '<input id="'+id+'_textld_l" type="hidden" style="display:none" value="0">\n';
s+= '<input id="'+id+'_textld_t" type="hidden" style="display:none" value="0">\n';
//last image loaded
s+= '<input id="'+id+'_imageld_w" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_imageld_h" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_imageld_l" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_imageld_t" type="hidden" style="display:none" value="1">\n';
s+= '<input id="'+id+'_actionOnMove" type="hidden" style="display:none" value="'+onMove+'">\n';
s+= '<input id="'+id+'_actionOnDone" type="hidden" style="display:none" value="'+onDone+'">\n';
s+= '<input id="'+id+'_actionOnDoubleclick" type="hidden" style="display:none" value="'+onDobleClick+'">\n';
s+= '<input id="'+id+'_actionOnMouseDown" type="hidden" style="display:none" value="'+onMouseDown+'">\n';
s+='</div>\n';
//document.title="=== "+id+" ==="+document.getElementById(id)+"===";
document.getElementById(id).innerHTML=s+document.getElementById(id).innerHTML;
document.getElementById(id+"_borderStyle").value=document.getElementById(id+"_frame_root").style.borderStyle;
document.getElementById(id+"_borderWidth").value=document.getElementById(id+"_frame_root").style.borderWidth;
}
function frAmeselShow (id) {
if (!document.getElementById(id+"_snap_hw")) return;
var snap_hw=parseInt(document.getElementById(id+"_snap_hw").value);
var row=parseInt(document.getElementById(id+"_realOuterWidth" ).value);
var roh=parseInt(document.getElementById(id+"_realOuterHeight").value);
var riw=parseInt(document.getElementById(id+"_realInnerWidth" ).value);
var rih=parseInt(document.getElementById(id+"_realInnerHeight").value);
var ril=parseInt(document.getElementById(id+"_realInnerLeft" ).value);
var rit=parseInt(document.getElementById(id+"_realInnerTop" ).value);
var scale=parseFloat(document.getElementById(id+"_outerPixelScale").value)
var bw= (document.getElementById(id+"_frame_root").style.borderStyle!="none")?parseInt (document.getElementById(id+"_frame_root").style.borderWidth):0;
var ms= parseFloat(document.getElementById(id+"_magnifierScale" ).value);
var ow = Math.round (row*scale);
var oh = Math.round (roh*scale);
var iw= Math.round (riw*scale);
var ih= Math.round (rih*scale);
var il= Math.round (ril*scale);
var it= Math.round (rit*scale);
var snap_hw2=2*snap_hw;
document.getElementById(id+"_n" ).style.height=snap_hw2;
document.getElementById(id+"_n" ).style.width= iw-snap_hw2;
document.getElementById(id+"_n" ).style.left= il+snap_hw;
document.getElementById(id+"_n" ).style.top= it-snap_hw;
document.getElementById(id+"_ne").style.width= snap_hw2;
document.getElementById(id+"_ne").style.height=snap_hw2;
document.getElementById(id+"_ne").style.left= il+iw-snap_hw;
document.getElementById(id+"_ne").style.top= it-snap_hw;
document.getElementById(id+"_e" ).style.width= snap_hw2;
document.getElementById(id+"_e" ).style.height=ih-snap_hw2;
document.getElementById(id+"_e" ).style.left= il+iw-snap_hw;
document.getElementById(id+"_e" ).style.top= it+snap_hw;
document.getElementById(id+"_se").style.width= snap_hw2;
document.getElementById(id+"_se").style.height=snap_hw2;
document.getElementById(id+"_se").style.left= il+iw-snap_hw;
document.getElementById(id+"_se").style.top= it+ih-snap_hw;
document.getElementById(id+"_s" ).style.height=snap_hw2;
document.getElementById(id+"_s" ).style.width= iw-snap_hw2;
document.getElementById(id+"_s" ).style.left= il+snap_hw;
document.getElementById(id+"_s" ).style.top= it+ih-snap_hw;
document.getElementById(id+"_sw").style.width= snap_hw2;
document.getElementById(id+"_sw").style.height=snap_hw2;
document.getElementById(id+"_sw").style.left= il-snap_hw;
document.getElementById(id+"_sw").style.top= it+ih-snap_hw;
document.getElementById(id+"_w" ).style.width= snap_hw2;
document.getElementById(id+"_w" ).style.height=ih-snap_hw2;
document.getElementById(id+"_w" ).style.left= il-snap_hw;
document.getElementById(id+"_w" ).style.top= it+snap_hw;
document.getElementById(id+"_nw").style.width= snap_hw2;
document.getElementById(id+"_nw").style.height=snap_hw2;
document.getElementById(id+"_nw").style.left= il-snap_hw;
document.getElementById(id+"_nw").style.top= it-snap_hw;
document.getElementById(id+"_c").style.top= it+snap_hw;
document.getElementById(id+"_c").style.left= il+snap_hw;
document.getElementById(id+"_c").style.width= iw-snap_hw2;
document.getElementById(id+"_c").style.height= ih-snap_hw2;
document.getElementById(id+"_frame_root").style.width=iw-bw;
document.getElementById(id+"_frame_root").style.height=ih-bw;
document.getElementById(id+"_frame_root").style.left= il-Math.round(bw/2);
document.getElementById(id+"_frame_root").style.top= it-Math.round(bw/2);;
if (document.getElementById(id+"_frame_image")) {
if (ms>0) {
document.getElementById(id+"_frame_image").style.width= Math.round(ms*row);
document.getElementById(id+"_frame_image").style.height=Math.round(ms*roh);
document.getElementById(id+"_frame_image").style.left= -Math.round(ril/(row-riw)*(ms*row -iw+bw));
document.getElementById(id+"_frame_image").style.top= -Math.round(rit/(roh-rih)*(ms*roh -ih+bw));
} else {
// document.getElementById(id+"_frame_image").style.width="100%";
// document.getElementById(id+"_frame_image").style.height="100%";
document.getElementById(id+"_frame_image").style.width= Math.round(parseInt(document.getElementById(id+"_imageld_w").value)*scale);
document.getElementById(id+"_frame_image").style.height=Math.round(parseInt(document.getElementById(id+"_imageld_h").value)*scale);
document.getElementById(id+"_frame_image").style.left= Math.round((parseInt(document.getElementById(id+"_imageld_l").value)-
parseInt(document.getElementById(id+"_realInnerLeft").value))*scale);
document.getElementById(id+"_frame_image").style.top= Math.round((parseInt(document.getElementById(id+"_imageld_t").value)-
parseInt(document.getElementById(id+"_realInnerTop").value))*scale);
}
document.getElementById(id+"_frame_rootClip").style.clip="rect("+0+"px, "+(iw-bw)+"px, "+(ih-bw)+"px, "+"0"+"px)"
document.getElementById(id+"_frame_rootClip").style.width=(iw-bw)+"px";
document.getElementById(id+"_frame_rootClip").style.height=(ih-bw)+"px"
document.getElementById(id+"_frame_rootClip").style.left="0px";
document.getElementById(id+"_frame_rootClip").style.top="0px";
}
frAmeselAllTextFromInternal (id);
}
function frAmeselAllTextFromInternal (id) {
var rel= document.getElementById(id+"_relative").value?true:false;
var ow=parseInt(document.getElementById(id+"_realOuterWidth" ).value);
var oh=parseInt(document.getElementById(id+"_realOuterHeight").value);
var iw=parseInt(document.getElementById(id+"_realInnerWidth" ).value);
var ih=parseInt(document.getElementById(id+"_realInnerHeight").value);
var il=parseInt(document.getElementById(id+"_realInnerLeft" ).value);
var it=parseInt(document.getElementById(id+"_realInnerTop" ).value);
if (rel) {
il=(ow==iw)?50:Math.round(10000*il/(ow-iw))/100;
it=(oh==ih)?50:Math.round(10000*it/(oh-ih))/100;
iw=Math.round(10000*iw/ow)/100;
ih=Math.round(10000*ih/oh)/100;
}
document.getElementById(id+'_textld_w').value=iw;
document.getElementById(id+'_textld_h').value=ih;
document.getElementById(id+'_textld_l').value=il;
document.getElementById(id+'_textld_t').value=it;
if (document.getElementById(id+'_text_w').value && (document.getElementById(document.getElementById(id+'_text_w').value).myfocus!=true))
document.getElementById(document.getElementById(id+'_text_w').value).value=iw;
if (document.getElementById(id+'_text_h').value && (document.getElementById(document.getElementById(id+'_text_h').value).myfocus!=true))
document.getElementById(document.getElementById(id+'_text_h').value).value=ih;
if (document.getElementById(id+'_text_l').value && (document.getElementById(document.getElementById(id+'_text_l').value).myfocus!=true))
document.getElementById(document.getElementById(id+'_text_l').value).value=il;
if (document.getElementById(id+'_text_t').value && (document.getElementById(document.getElementById(id+'_text_t').value).myfocus!=true))
document.getElementById(document.getElementById(id+'_text_t').value).value=it;
}
function frAmeselSetResizeEn (id,en) {
document.getElementById(id+"_n" ).style.cursor=en?"n-resize":"move";
document.getElementById(id+"_ne").style.cursor=en?"ne-resize":"move";
document.getElementById(id+"_e" ).style.cursor=en?"e-resize":"move";
document.getElementById(id+"_se").style.cursor=en?"se-resize":"move";
document.getElementById(id+"_s" ).style.cursor=en?"s-resize":"move";
document.getElementById(id+"_sw").style.cursor=en?"sw-resize":"move";
document.getElementById(id+"_w" ).style.cursor=en?"w-resize":"move";
document.getElementById(id+"_nw").style.cursor=en?"nw-resize":"move";
}
function frAmeselGetResizeEn (id) {return (document.getElementById(id+"_n" ).style.cursor!="move"); }
function frAmeselSetRelative (id,r) {
document.getElementById(id+"_relative" ).value=r?"1":"";
frAmeselAllTextFromInternal (id);
}
function frAmeselGetRelative (id) {
return (document.getElementById(id+"_relative" ).value)?true:false;
}
function frAmeselSetOuterScaled (id,wh) { // preserve proportion of the frame to the whole window while changing window size
var oldwh= frAmeselGetOuter (id);
var ow=parseInt(document.getElementById(id).style.width);
var oh=parseInt(document.getElementById(id).style.height);
var bw=parseInt(document.getElementById(id+'_frameBorder').style.borderWidth);
if (document.getElementById(id+'_frameBorder').style.borderStyle == 'none') bw=0;
if (!(bw>0)) bw=0;
ow-=2*bw;
oh-=2*bw;
var scale=ow/wh.w; if ((oh/wh.h) < scale) scale=oh/wh.h;
document.getElementById(id+"_realOuterWidth" ).value=wh.w;
document.getElementById(id+"_realOuterHeight").value=wh.h;
document.getElementById(id+"_outerPixelScale").value=scale;
document.getElementById(id+'_frameBorder').style.width=Math.round(wh.w*scale);
document.getElementById(id+'_frameBorder').style.height=Math.round(wh.h*scale);
var wi=frAmeselGetInner (id);
wi.w=Math.round (wi.w*wh.w/oldwh.w);
wi.h=Math.round (wi.h*wh.h/oldwh.h);
wi.l=Math.round (wi.l*wh.w/oldwh.w);
wi.t=Math.round (wi.t*wh.h/oldwh.h);
frAmeselSetInner (id,wi);
}
function frAmeselSetOuter (id,wh) {
var ow=parseInt(document.getElementById(id).style.width);
var oh=parseInt(document.getElementById(id).style.height);
var bw=parseInt(document.getElementById(id+'_frameBorder').style.borderWidth);
if (document.getElementById(id+'_frameBorder').style.borderStyle == 'none') bw=0;
if (!(bw>0)) bw=0;
ow-=2*bw;
oh-=2*bw;
var scale=ow/wh.w; if ((oh/wh.h) < scale) scale=oh/wh.h;
document.getElementById(id+"_realOuterWidth" ).value=wh.w;
document.getElementById(id+"_realOuterHeight").value=wh.h;
document.getElementById(id+"_outerPixelScale").value=scale;
document.getElementById(id+'_frameBorder').style.width=Math.round(wh.w*scale);
document.getElementById(id+'_frameBorder').style.height=Math.round(wh.h*scale);
}
function frAmeselFillParent (id) {
if (!document.getElementById(id)) return;
if (!document.getElementById(id+"_realOuterWidth" )) return;
var ow=parseInt(document.getElementById(id).parentNode.style.width);
var oh=parseInt(document.getElementById(id).parentNode.style.height);
var wh={w:parseInt(document.getElementById(id+"_realOuterWidth" ).value),
h:parseInt(document.getElementById(id+"_realOuterHeight").value)};
document.getElementById(id).style.width= ow;
document.getElementById(id).style.height= oh;
document.getElementById(id).style.left=0;
document.getElementById(id).style.top=0;
var bw=parseInt(document.getElementById(id+'_frameBorder').style.borderWidth);
if (document.getElementById(id+'_frameBorder').style.borderStyle == 'none') bw=0;
if (!(bw>0)) bw=0;
ow-=2*bw;
oh-=2*bw;
var scale=ow/wh.w; if ((oh/wh.h) < scale) scale=oh/wh.h;
document.getElementById(id+"_outerPixelScale").value=scale;
document.getElementById(id+'_frameBorder').style.width=Math.round(wh.w*scale);
document.getElementById(id+'_frameBorder').style.height=Math.round(wh.h*scale);
}
function frAmeselGetOuter (id) {
return {w:parseInt(document.getElementById(id+"_realOuterWidth" ).value),
h:parseInt(document.getElementById(id+"_realOuterHeight").value)};
}
function frAmeselSetZindexHandles(id,z) {
document.getElementById(id+"_n" ).style.zIndex=z;
document.getElementById(id+"_ne").style.zIndex=z;
document.getElementById(id+"_e" ).style.zIndex=z;
document.getElementById(id+"_se").style.zIndex=z;
document.getElementById(id+"_s" ).style.zIndex=z;
document.getElementById(id+"_sw").style.zIndex=z;
document.getElementById(id+"_w" ).style.zIndex=z;
document.getElementById(id+"_nw").style.zIndex=z;
document.getElementById(id+"_c" ).style.zIndex=z;
}
function frAmeselSetZindexFrame(id,z) {
document.getElementById(id+"_frame_root" ).style.zIndex=z;
}
function frAmeselGetZindexHandles(id) {
return parseInt(document.getElementById(id+"_n" ).style.zIndex);
}
function frAmeselGetZindexFrame(id) {
return parseInt(document.getElementById(id+"_frame_root" ).style.zIndex);
}
function frAmeselSetInner (id,whlt) {
// alert (id);
// debugWindowShow(document.getElementById("idMagnifier_frAmesel").parentNode.innerHTML);
document.getElementById(id+"_realInnerWidth" ).value=whlt.w;
document.getElementById(id+"_realInnerHeight").value=whlt.h;
document.getElementById(id+"_realInnerLeft" ).value= whlt.l;
document.getElementById(id+"_realInnerTop").value= whlt.t;
document.getElementById(id+"_lastInnerWidth" ).value=whlt.w;
document.getElementById(id+"_lastInnerHeight").value=whlt.h;
document.getElementById(id+"_lastInnerLeft" ).value= whlt.l;
document.getElementById(id+"_lastInnerTop").value= whlt.t;
}
function frAmeselCenterInner (id) {
var m= Math.round((parseInt(document.getElementById(id+"_realOuterWidth" ).value)-
parseInt(document.getElementById(id+"_realInnerWidth" ).value))/2);
document.getElementById(id+"_realInnerLeft" ).value= m;
document.getElementById(id+"_lastInnerLeft" ).value= m;
var m= Math.round((parseInt(document.getElementById(id+"_realOuterHeight" ).value)-
parseInt(document.getElementById(id+"_realInnerHeight" ).value))/2);
document.getElementById(id+"_realInnerTop" ).value= m;
document.getElementById(id+"_lastInnerTop" ).value= m;
}
function frAmeselGetInner (id) {
return {w:parseInt(document.getElementById(id+"_realInnerWidth" ).value),
h:parseInt(document.getElementById(id+"_realInnerHeight").value),
l:parseInt(document.getElementById(id+"_realInnerLeft" ).value),
t:parseInt(document.getElementById(id+"_realInnerTop" ).value)};
}
function frAmeselSetMagnification (id,m) {
document.getElementById(id+"_magnifierScale" ).value=m;
}
function frAmeselGetMagnification (id) {
return parseInt(document.getElementById(id+"_magnifierScale" ).value);
}
function frAmeselSetSnap (id,m) {
document.getElementById(id+"_snap_hw" ).value=m;
}
function frAmeselGetSnap (id) {
return parseInt(document.getElementById(id+"_snap_hw" ).value);
}
function frAmeselSetBorderWidth (id,m) {
document.getElementById(id+"_borderWidth" ).value=m;
document.getElementById(id+"_frame_root").style.borderWidth=m;
}
function frAmeselGetBorderWidth (id) {
return parseInt(document.getElementById(id+"_borderWidth" ).value);
}
function frAmeselSetBorderStyle (id,m) {
document.getElementById(id+"_borderStyle" ).value=m;
document.getElementById(id+"_frame_root").style.borderStyle=m;
}
function frAmeselGetBorderStyle (id) {
return parseInt(document.getElementById(id+"_borderStyle" ).value);
}
function frAmeselSetImage (id,url) {
document.getElementById(id+"_frame_image_img" ).src=url;
if (parseFloat(document.getElementById(id+"_magnifierScale" ).value) >0) {// magnifier mode
document.getElementById(id+"_imageld_w").value=document.getElementById(id+"_realOuterWidth").value;
document.getElementById(id+"_imageld_h").value=document.getElementById(id+"_realOuterHeight").value;
document.getElementById(id+"_imageld_l").value=0;
document.getElementById(id+"_imageld_t").value=0;
} else { // mode WOI
document.getElementById(id+"_imageld_w").value=document.getElementById(id+"_realInnerWidth").value;
document.getElementById(id+"_imageld_h").value=document.getElementById(id+"_realInnerHeight").value;
document.getElementById(id+"_imageld_l").value=document.getElementById(id+"_realInnerLeft").value;
document.getElementById(id+"_imageld_t").value=document.getElementById(id+"_realInnerTop").value;
}
frAmeselShow (id); // isn't it duplicate? (at the end it updates text fields from the internal variables)
}
function frAmeselSetBorderShow (id,showb) {
if (showb) document.getElementById(id+"_frame_root").style.borderStyle=document.getElementById(id+"_borderStyle" ).value; // stored style
else document.getElementById(id+"_frame_root").style.borderStyle="none";
}
function frAmeselOnTextChange(iid,d) { //"'+id+'","w")
var id=iid.substr(0,iid.indexOf("frAmesel"))+"frAmesel";
var v=document.getElementById(document.getElementById(id+'_text_'+d).value).value;
if (v==document.getElementById(id+'_textld_'+d).value) return; // no change
var rel= document.getElementById(id+"_relative").value?true:false;
if (rel) v= Math.round(parseFloat(v)*100)/100;
else v=parseInt(v);
if (isNaN(v)) {
frAmeselAllTextFromInternal (id);
return;
}
var minWidth;
var ow, iw, il, iw0,il0;
if ((d=="w") || (d=="l")) {
minWidth=parseInt(document.getElementById(id+"_minWidth" ).value);
ow=parseInt(document.getElementById(id+"_realOuterWidth" ).value);
iw=parseInt(document.getElementById(id+"_realInnerWidth" ).value);
il=parseInt(document.getElementById(id+"_realInnerLeft" ).value);
} else {
minWidth=parseInt(document.getElementById(id+"_minHeight" ).value);
ow=parseInt(document.getElementById(id+"_realOuterHeight" ).value);
iw=parseInt(document.getElementById(id+"_realInnerHeight" ).value);
il=parseInt(document.getElementById(id+"_realInnerTop" ).value);
}
iw0=iw;
il0=il;
if ((d=="w") || (d=="h")) {
if (rel) v=Math.round (v*ow/100);
if (v>ow) v=ow;
if (v<minWidth) v=minWidth;
// can fit without moving il?
if (rel) {
il-=Math.round ((v-iw0)/2);
if (il<0) il =0;
else if (il>(ow-v)) il= ow-v;
} else {
if (il>(ow-v)) il=ow-v;
}
iw=v;
} else {
if (rel) v=Math.round (v*(ow-iw)/100);
if (v<0) v=0;
if (v>ow-iw) v=ow-iw;
il=v;
}
if ((il != il0) || (iw != iw0)) {
if ((d=="w") || (d=="l")) {
document.getElementById(id+"_realInnerWidth" ).value=iw;
// document.getElementById(id+"_lastInnerWidth" ).value=iw;
document.getElementById(id+"_realInnerLeft" ).value=il;
// document.getElementById(id+"_lastInnerLeft" ).value=il;
} else {
document.getElementById(id+"_realInnerHeight").value=iw;
// document.getElementById(id+"_lastInnerHeight").value=iw;
document.getElementById(id+"_realInnerTop" ).value=il;
// document.getElementById(id+"_lastInnerTop" ).value=il;
}
frAmeselActOnDone(id);
}
frAmeselShow(id);
}
function frAmeselPressed(){
if (document.frAmeselTimerID) {
clearTimeout(document.frAmeselTimerID);
document.frAmeselTimerID=null;
if (document.debug & 16) document.title+="^";
}
}
function frAmeselMousedownProcess(e) {
var targ;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
document.frAmeselName=targ.id.substr(0,targ.id.indexOf("frAmesel"))+"frAmesel";
var doubleclick=(document.frAmeselTimerID != null);
if (document.debug & 16) document.title+=doubleclick?"D":"S";
if (document.frAmeselTimerID) {
clearTimeout(document.frAmeselTimerID);
document.frAmeselTimerID=null;
}
document.frAmeselTimerID = self.setTimeout("frAmeselPressed();", document.doubleclickDelay);
if (doubleclick) {
frAmeselActOnDoubleclick (document.frAmeselName);
return;
}
var t=targ.id.substr(document.frAmeselName.length+1);
document.frAmeselStartDrag={x:e.pageX,y:e.pageY};
var shiftPressed=e.shiftKey;
var a=1/parseFloat(document.getElementById(document.frAmeselName+"_outerPixelScale").value); //a>1
var b=e.shiftKey?1:a;
if (t=="n" ) document.frAmeselVector={l:0,t:1,w: 0,h:-1};
else if (t=="ne") document.frAmeselVector={l:0,t:b,w: b,h:-b};
else if (t=="e" ) document.frAmeselVector={l:0,t:0,w: 1,h: 0};
else if (t=="se") document.frAmeselVector={l:0,t:0,w: b,h: b};
else if (t=="s" ) document.frAmeselVector={l:0,t:0,w: 0,h: 1};
else if (t=="sw") document.frAmeselVector={l:b,t:0,w:-b,h: b};
else if (t=="w" ) document.frAmeselVector={l:1,t:0,w:-1,h: 0};
else if (t=="nw") document.frAmeselVector={l:b,t:b,w:-b,h:-b};
else if (t=="c" ) document.frAmeselVector={l:b,t:b,w: 0,h: 0};
else return;
document.frAmeselStartInternal={w:parseInt(document.getElementById(document.frAmeselName+"_realInnerWidth" ).value),
h:parseInt(document.getElementById(document.frAmeselName+"_realInnerHeight").value),
l:parseInt(document.getElementById(document.frAmeselName+"_realInnerLeft" ).value),
t:parseInt(document.getElementById(document.frAmeselName+"_realInnerTop" ).value)};
document.frAmeselDragging=true;
mousemoveProcess(e);
var act= document.getElementById(document.frAmeselName+"_actionOnMouseDown").value;
if (act) eval (act);
}
function frAmeselMousemoveProcess(e) {
var x=e.pageX-document.frAmeselStartDrag.x;
var y=e.pageY-document.frAmeselStartDrag.y;
if (document.debug & 32) document.title+=" x="+x + " y="+y;
var id=document.frAmeselName;
var contW=true;
var contH=true;
if ((document.frAmeselVector.l!=0) || (document.frAmeselVector.w!=0)) { // just to save time
var row=parseInt(document.getElementById(id+"_realOuterWidth").value);
var riw=parseInt(document.getElementById(id+"_realInnerWidth").value);
var ril=parseInt(document.getElementById(id+"_realInnerLeft").value);
var mw= parseInt(document.getElementById(id+"_minWidth").value);
}
if ((document.frAmeselVector.t!=0) || (document.frAmeselVector.h!=0)) { // just to save time
var roh=parseInt(document.getElementById(id+"_realOuterHeight").value);
var rih=parseInt(document.getElementById(id+"_realInnerHeight").value);
var rit=parseInt(document.getElementById(id+"_realInnerTop").value);
var mh=parseInt(document.getElementById(id+"_minHeight").value);
}
if (document.frAmeselVector.l!=0) {
v= Math.round(document.frAmeselStartInternal.l+x*document.frAmeselVector.l);
if (document.frAmeselVector.w==0) { // moving as a whole
if (v>(row-riw)) v= row-riw;
} else { // moving just left border
if (v> (ril+riw-mw)) {
v= ril+riw-mw;
}
}
if (v<0) v=0;
if (document.frAmeselVector.w!=0) { // just left moving
document.getElementById(id+"_realInnerWidth").value= document.frAmeselStartInternal.l+document.frAmeselStartInternal.w-v;
contW=false; // will not process that branch
}
ril=v;
document.getElementById(id+"_realInnerLeft").value= ril;
}
if (document.frAmeselVector.t!=0) {
v= Math.round(document.frAmeselStartInternal.t+y*document.frAmeselVector.t);
if (document.frAmeselVector.h==0) {
if (v>(roh-rih)) v= roh-rih;
} else { // moving just top border
if (v> (rit+rih-mh)) {
v= rit+rih-mh;
}
}
if (v<0) v=0;
if (document.frAmeselVector.h!=0) { // just top moving
document.getElementById(id+"_realInnerHeight").value= document.frAmeselStartInternal.t+document.frAmeselStartInternal.h-v;
contH=false; // will not process that branch
}
rit=v;
document.getElementById(id+"_realInnerTop").value= rit;
}
if (contW &&( document.frAmeselVector.w!=0)) {
v= Math.round(document.frAmeselStartInternal.w+x*document.frAmeselVector.w);
if (v>(row-ril)) v = row-ril;
if (v<mw) v=mw;
document.getElementById(id+"_realInnerWidth").value= v;
}
if (contH && (document.frAmeselVector.h!=0)) {
v= Math.round(document.frAmeselStartInternal.h+y*document.frAmeselVector.h);
if (v>(roh-rit)) v = roh-rit;
if (v<mh) v=mh;
document.getElementById(id+"_realInnerHeight").value= v;
}
frAmeselActOnChange (id);
frAmeselShow (id);
}
function frAmeselMouseupProcess(e) {
frAmeselActOnDone (document.frAmeselName);
}
function frAmeselActOnDone (id) {
var act= document.getElementById(id+"_actionOnDone").value;
if (act && (
(document.getElementById(id+"_lastInnerWidth").value!= document.getElementById(id+"_realInnerWidth").value) ||
(document.getElementById(id+"_lastInnerHeight").value!=document.getElementById(id+"_realInnerHeight").value) ||
(document.getElementById(id+"_lastInnerLeft").value!= document.getElementById(id+"_realInnerLeft").value) ||
(document.getElementById(id+"_lastInnerTop").value!= document.getElementById(id+"_realInnerTop").value))) {
eval (act);
document.getElementById(id+"_lastInnerWidth").value= document.getElementById(id+"_realInnerWidth").value;
document.getElementById(id+"_lastInnerHeight").value=document.getElementById(id+"_realInnerHeight").value;
document.getElementById(id+"_lastInnerLeft").value= document.getElementById(id+"_realInnerLeft").value;
document.getElementById(id+"_lastInnerTop").value= document.getElementById(id+"_realInnerTop").value;
}
}
function frAmeselActOnChange (id) {
var act= document.getElementById(id+"_actionOnMove").value;
if (act && (
(document.getElementById(id+"_lastInnerWidth").value!= document.getElementById(id+"_realInnerWidth").value) ||
(document.getElementById(id+"_lastInnerHeight").value!=document.getElementById(id+"_realInnerHeight").value) ||
(document.getElementById(id+"_lastInnerLeft").value!= document.getElementById(id+"_realInnerLeft").value) ||
(document.getElementById(id+"_lastInnerTop").value!= document.getElementById(id+"_realInnerTop").value)))
{
eval (act);
document.getElementById(id+"_lastInnerWidth").value= document.getElementById(id+"_realInnerWidth").value;
document.getElementById(id+"_lastInnerHeight").value=document.getElementById(id+"_realInnerHeight").value;
document.getElementById(id+"_lastInnerLeft").value= document.getElementById(id+"_realInnerLeft").value;
document.getElementById(id+"_lastInnerTop").value= document.getElementById(id+"_realInnerTop").value;
}
}
function frAmeselActOnDoubleclick (id) {
var act= document.getElementById(id+"_actionOnDoubleclick").value;
if (act) eval (act);
}
/*
*! -----------------------------------------------------------------------------**
*! elphelSliders.js
*!
*! Copyright (C) 2006-2007 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: elphelSliders2.js,v $
*! Revision 1.6 2008/12/13 23:39:16 elphel
*! typo
*!
*! Revision 1.5 2008/12/10 03:06:07 elphel
*! Additional non-linear slider modes (there were only linear and logarithmic) to stretch scale near 100%
*!
*! Revision 1.4 2008/12/09 19:25:17 elphel
*! After disabling default actions onmousedown - enabled all input text fields: onmousedown="this.select()" (otherwise they did not get focus when clicking them)
*!
*! Revision 1.3 2008/12/09 16:29:54 elphel
*! Added event.preventDefault() here and there. Really helped - with the current FF buttons were dragged away like images (before I could only fight it using background images, not the regular ones)
*!
*! Revision 1.2 2008/12/07 23:07:17 elphel
*! Fixing few remaining "fights" between user and the camera (when some parameter is changed and camera changes it back)
*!
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.2 2008/11/10 19:48:47 elphel
*! blocking text fields updates while they are in focus
*!
*! Revision 1.1 2008/04/22 22:21:31 elphel
*! Started camvc2 that currently uses most of the same images and javascript files as camvc
*!
*! Revision 1.1.1.1 2007/09/19 04:51:17 elphel
*! This is a fresh tree based on elphel353-2.10
*!
*! Revision 1.2 2007/09/19 04:51:17 elphel
*! Upgraded license (header)
*!
*!
*/
/*
* Create slider into an existent DIV element (the name should end with the "slIder"
* It is convenient to use an array for initialization, as shown in the code above - createAllslIders()
*/
document.slIderDragging=false; // for some reasons without such assignment (only functions) none of the functions gets visible
function createSlider (id, //my1_slIder -should end with "_slIder"
buttonWidth, // there will be a image button to the left of the slider
buttonUrl, //supports switching between *.* and *_press.* (fixed some problems in original code
pointerWidth, // width of the slider pointer
pointerUrl, // url of the pointer image
// pointerDisabledURL, // pointer for the disabled slider (indicator only)
sliderLength, // length of a slider itself (the rest will be used fro input text field
railLeftUrl, // left end of rail image (should be same width as pointer_width)
railRightUrl, // right end of rail image (should be same width as pointer_width)
railMiddleUrl,// may be 1 pixel wide - will be streched as needed
dummyImageUrl, // 1x1 pixel transparent image to fill empty div (maybe will remove it)
textFieldSize,
textFieldMaxlen,
textFieldStyle,
textFieldUnits, // to be written after the input window
textFieldUnitsStyle,
lowLimit,
highLimit,
logarithm, /// 0 - linear, 1 - logarithmic scale, 2 - highLimit*Math.pow(k, lowLimit), 3 - highLimit*(1-Math.pow((1-k), lowLimit))
decimals, // number of decimals after the point in the text field
fineControl, // percents of the slider height used for fine control - positive - top, negative - bottom
// in the following actions id is defined as the outer DIV id. so "alert(id)" as the value will work
actionOnChange, // action to be "eval()" when slider is moved. id is defined as the outer DIV id
actionOnDone, // action when text field is changed or slider button released
actionOnButton, // action when (right) button is pressed
actionOnDoubleclick) {//action on slider double click (i.e. auto on/off)
var h=document.getElementById(id).style.height;
var iHTML= "";
// <div id="my1_slIder" style="position:absolute; left:100; top:50; width:356; height:25;">
if (buttonWidth>0) {
iHTML+=
'<div id="'+id+'_button" style="position:absolute; left:0; top:0; width:'+buttonWidth+'; height:'+h+';">\n';
if (buttonUrl)
// if buttonURL is not specified - just the room will be left for the button that should be generated separately
iHTML+= '<img id="'+id+'_buttonImg" src="'+buttonUrl+'" onmousedown="slIderButtonMouse(this.id,'+"'on'"+',event);" onmouseup="slIderButtonMouse(this.id,'+"'off'"+',event);"/>\n';
iHTML+='</div>\n';
}
iHTML+=
'<div id="'+id+'_slider" style="cursor:pointer;position:absolute; left:'+buttonWidth+'; top:0; width:'+sliderLength+'; height:'+h+';">\n'+
'<div id="'+id+'_divbackground" style="position:absolute; left:0; top:0; width:'+sliderLength+'; height:'+h+';">\n'+
'<div id="'+id+'_1" style="position:absolute; left:0; top:0; width:'+pointerWidth+'; height:'+h+';">\n'+
'<img id="'+id+'_1i" src="'+railLeftUrl+'" style="width:'+pointerWidth+'; height:'+h+';">\n'+
'</div>\n'+
'<div id="'+id+'_2" style="position:absolute; left:'+pointerWidth+'; top:0; width:'+(sliderLength-2*pointerWidth)+'; height:'+h+';">\n'+
'<img id="'+id+'_2i" src="'+railMiddleUrl+'" style="width:'+(sliderLength-2*pointerWidth)+'; height:'+h+';">\n'+
'</div>\n'+
'<div id="'+id+'_3" style="position:absolute; left:'+(sliderLength-pointerWidth)+'; top:0; width:'+pointerWidth+'; height:'+h+';">\n'+
'<img id="'+id+'_3i" src="'+railRightUrl+'" style="width:'+pointerWidth+'; height:'+h+';">\n'+
'</div>\n'+
'</div>\n'+
'<div id="'+id+'_divslider" style="position:absolute; left:0; top:0; width:'+pointerWidth+'; height:'+h+'; z-index:1;">\n'+
'<img id="'+id+'_divsliderimg" src="'+pointerUrl+'" style="width:'+pointerWidth+';height:'+h+'">\n'+
'</div>\n'+
'<div id="'+id+'_divcover" style="position:absolute; left:0;top:0;width:100%;height:100%;z-index:2;" >\n'+
'<img src="'+dummyImageUrl+'" style="width:1; height:1">\n'+
'</div>\n'+
'</div>\n'+
'<div id="'+id+'_divText" style="float:right;">\n'+
'<input type="text" id="'+id+'_Text" style="'+textFieldStyle+'" size="'+textFieldSize+'" maxlength="'+textFieldMaxlen+'" value="" onChange="updateSliderFromTextID(this.id);" onfocus="this.myfocus=true;" onblur="this.myfocus=false;updateSliderFromTextID(this.id);" onmousedown="this.select();" >\n';
if (textFieldUnits) iHTML+=
'<span id="'+id+'_Units" style="'+textFieldUnitsStyle+'">'+textFieldUnits+'</span>\n';
iHTML+=
'</div>\n'+
'<input type="hidden" style="display:none" id="'+id+'_lastValueSet" value="">\n'+
'<input type="hidden" style="display:none" id="'+id+'_forceUpdate" value="">\n'+
'<input type="hidden" style="display:none" id="'+id+'_lowLimit" value="'+lowLimit+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_highLimit" value="'+highLimit+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_logarithm" value="'+logarithm+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_Decimals" value="'+decimals+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_actionOnChange" value="'+actionOnChange+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_actionOnDone" value="'+actionOnDone+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_actionOnDoubleclick" value="'+actionOnDoubleclick+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_actionOnButton" value="'+actionOnButton+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_fineControl" value="'+fineControl+'">\n'+
'<input type="hidden" style="display:none" id="'+id+'_sliderValue" value="">\n'+
'</div>\n';
// If you uncomment the following alert, it will show all the HTML code generated for each slider
// alert(iHTML);
document.getElementById(id).innerHTML=iHTML;
document.sliderTimerID=null;
}
/*
* Functions for interaction with the slider. "id" here is the parent DIV id
*/
/*
* Set inernal value, slider and text to specified value
*/
function setSliderLow(id,value) {
var v=getSliderValue(id);
document.getElementById(id+"_lowLimit").value=value;
setSliderAndText(id,v);
}
function setSliderHigh(id,value) {
var v=getSliderValue(id);
document.getElementById(id+"_highLimit").value=value;
setSliderAndText(id,v);
}
function getSliderLow(id) {
return document.getElementById(id+"_lowLimit").value;
}
function getSliderHigh(id) {
return document.getElementById(id+"_highLimit").value;
}
function forceSliderAndText(id,value) {
//document.title+="+";
// if ((document.slIderDragging) && (document.slIderName==id)) return; // no updating position by external command while dragging
setSliderValueOnly(id,value);
document.getElementById(id+"_lastValueSet").value=document.getElementById(id+"_sliderValue").value; // to prevent triggering "onDone" "onChange" if the data did not change
document.getElementById(id+"_forceUpdate").value=1; /// perform actOnDone in any case
setSliderText(id);
updateSliderFromValue(id);
sliderActOnDone (id); /// Seeems nothing triggers it otherwise?
}
/**
* @brief this function will not generate action on done if result will be the same as set here. See forceSliderAndText()
* @param id slider Id
* @param value value to set slider to
*/
function setSliderAndText(id,value) {
//document.title+="-";
if ((document.slIderDragging) && (document.slIderName==id)) return; // no updating position by external command while dragging
setSliderValueOnly(id,value);
document.getElementById(id+"_lastValueSet").value=document.getElementById(id+"_sliderValue").value; // to prevent triggering "onDone" "onChange" if the data did not change
document.getElementById(id+"_forceUpdate").value=0; /// only perform actOnDone if the velue will be different
setSliderText(id);
updateSliderFromValue(id);
// sliderActOnDone (id);
}
/*
* returns float value
*/
// uses internal value of 0..1
function getSliderValue(id) {
var llm=parseFloat(document.getElementById(id+"_lowLimit").value);
var hlm=parseFloat(document.getElementById(id+"_highLimit").value);
var v=parseFloat(document.getElementById(id+"_sliderValue").value);
if (document.debug & 128) document.title=id+":"+v;
switch (document.getElementById(id+"_logarithm").value) {
case '0':
return llm+ v* (hlm-llm);
case '1':
llm=Math.log(llm);
hlm=Math.log(hlm);
return Math.exp(llm+ v* (hlm-llm));
case '2':
return hlm*Math.pow(v,llm);
case '3':
return hlm*(1.0-Math.pow((1.0-v),llm));
}
}
// input - the i/o value from low to high limit, possibly with logarithmic scale
function setSliderValueOnly(id,v) { // only sets internal value (0..1)
var llm=parseFloat(document.getElementById(id+"_lowLimit").value);
var hlm=parseFloat(document.getElementById(id+"_highLimit").value);
var pwr=llm;
if (parseInt(document.getElementById(id+"_logarithm").value)>1) llm=0;
if (!((v>=llm) && (v<=hlm))) {
if (v>hlm) v=hlm;
else if (v<llm) v=llm;
else v= (llm+hlm)/2;
}
switch (document.getElementById(id+"_logarithm").value) {
case '0':
break;
case '1':
llm=Math.log(llm);
hlm=Math.log(hlm);
v= Math.log(v);
break;
case '2':
v=Math.pow((v/hlm), 1.0/pwr);
hlm=1.0;
break;
case '3':
v=1.0-Math.pow((1-(v/hlm)), 1.0/pwr);
hlm=1.0;
break;
}
document.getElementById(id+"_sliderValue").value=(v-llm)/(hlm-llm);
}
/*
* set slider text field to match internal value (0..1)
*/
function setSliderText(id) {
var rs=Math.pow(10,parseInt(document.getElementById(id+"_Decimals").value));
if (document.getElementById(id+"_Text").myfocus!=true) document.getElementById(id+"_Text").value=Math.round(getSliderValue(id)*rs)/rs;
}
/*
* redraw the slider to match the internal value
*/
function updateSliderFromValue(id) {
v=parseFloat(document.getElementById(id+"_sliderValue").value)
if (!((v>=0) && (v<=1))) {
if (v>1) v=1;
else if (v<0) v=0;
else v=0.5; // (if NaN)
}
if (document.debug & 128) document.title=document.slIderName;
var sliderLength=
document.getElementById(id+"_divslider").style.left=
Math.round((parseInt(document.getElementById(id+"_slider").style.width)-
parseInt(document.getElementById(id+"_divslider").style.width))*v);
}
/*
* Find correct ID (it is that of the text input field when called), update internal value slider and possibly call action on "done"
*/
function updateSliderFromTextID (id) {
var id;
if (id.indexOf("slIder")>=0) {
id=id.substr(0,id.indexOf("slIder"))+"slIder";
setSliderValueOnly(id,parseFloat(document.getElementById(id+"_Text").value));
updateSliderFromValue(id);
sliderActOnDone (id);
}
}
/*
* Enable (true) or disables (false) slider from dragging and the text field from changing - it still can be controlled by the setSliderAndText(id,value)
*/
function enableSlider(id,en) {
var sliderImg=document.getElementById(id+"_divsliderimg").src;
var i=sliderImg.indexOf("_disabled");
if (i>=0) sliderImg=sliderImg.substr(0,i)+sliderImg.substr(i+9); // remove "_disabled" if any
if (!en) sliderImg=sliderImg.substr(0,sliderImg.lastIndexOf("."))+"_disabled"+sliderImg.substr(sliderImg.lastIndexOf("."));
document.getElementById(id+"_divsliderimg").src= sliderImg;
document.getElementById(id+"_Text").disabled= !en;
}
function isEnabledSlider(id) {return !document.getElementById(id+"_Text").disabled;}
// '<img id="'+id+'_divsliderimg" src="'+pointerUrl+'" style="width:'+pointerWidth+';height:'+h+'">\n'+
/*
* Simple function to get the <img> element ID for the button (if you need to change it .src, i.e. for the toggle action)
*/
function getSliderButtonID(id) {
return id+"_buttonImg";
}
/*
*
* for direct access to the slider elements you may manually use the following suffixes of the element's IDs:
* _slIder - overall DIV element. May be "mouseover" between slider and the text field
* _slIder_divcover - covers all the slider itself (no button or text), but in IE will never trigger tooltips.
* Instead use (in addition as other browsers will use _slIder_divcover):
* _slIder_2i - image of the middle part of the slider rails (let's not bother with the ends) and
* _slIder_divsliderimg - image of the slider pointer
* _slIder_buttonImg - button to the left of the slider (if it exists)
* _slIder_Text - text input field
* _slIder_Units - it is a <span> so title, style and innerHTML might be changed among others
*
*/
/*
* Below are private functions for the sliders functioning:
*/
/*
* Here are the 3 mouse actions for the sliders mousdoun, mousmove and mouseup called from the main handlers.
*/
//instead of the shift - use "Y" - i.e if you take slider by the top it will be fine tuning?
// clearTimeout(document.buttonTimerID);
// document.buttonTimerID=null;
// if (document.buttonTimerID) {
// clearTimeout(document.buttonTimerID);
// document.buttonTimerID=null;
// }
// document.buttonTimerID = self.setTimeout("buttonLongPressed();", document.buttonDelay);
function sliderBallPressed(){
if (document.sliderTimerID) {
clearTimeout(document.sliderTimerID);
document.sliderTimerID=null;
}
}
function slIderMousedownProcess(e) {
var targ;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
document.slIderName=targ.id.substr(0,targ.id.indexOf("slIder"))+"slIder";
var doubleclick=(document.sliderTimerID != null);
if (document.sliderTimerID) {
clearTimeout(document.sliderTimerID);
document.sliderTimerID=null;
}
document.sliderTimerID = self.setTimeout("sliderBallPressed();", document.doubleclickDelay);
if (doubleclick) {
sliderActOnDoubleclick (document.slIderName);
return;
}
if (!document.getElementById(document.slIderName+"_Text").disabled) {
document.slIderBall= parseInt(document.getElementById(document.slIderName+"_divslider").style.width);
document.slIderRailLeft= Math.round(document.slIderBall/2);
document.slIderRailLength=parseInt(document.getElementById(document.slIderName+"_slider").style.width)- document.slIderBall;
var slIderPos= parseInt(document.getElementById(document.slIderName+"_divslider").style.left);
var offsetTrail =document.getElementById(document.slIderName+"_slider");
var absX0 = 0;
var absY0 = 0;
while (offsetTrail){
absX0 += parseInt(offsetTrail.offsetLeft);
absY0 += parseInt(offsetTrail.offsetTop);
offsetTrail = offsetTrail.offsetParent;
}
if ((navigator.userAgent.indexOf('Mac') != -1) && typeof(document.body.leftMargin) != 'undefined') {
absX0 += parseInt(document.body.leftMargin);
absY0 += parseInt(document.body.topMargin);
}
var x=e.pageX-absX0-document.slIderRailLeft;
var y=e.pageY-absY0;
var fc=parseInt(document.getElementById(document.slIderName+"_fineControl").value);
if (fc) {
var h=parseInt(document.getElementById(document.slIderName).style.height);
fc=fc/100; if (fc>1) fc=1; else if (fc<-1) fc=-1;
fc= (
((fc>0) && (y < (h*fc))) ||
((fc<0) && (y > (h*(fc+1))))); // fine control
}
if ((x>=-document.slIderRailLeft) && (x<(document.slIderRailLength+document.slIderRailLeft))) { // else it is a button or text input
if (e.shiftKey || fc ) document.slIderstartFine= slIderPos;
else document.slIderstartFine=-1;
if (Math.abs(x-slIderPos)>document.slIderRailLeft) { //clicked outside ball
if (document.slIderstartFine>=0) x= (document.slIderFine*document.slIderstartFine+x)/(document.slIderFine+1);
if (x<0) x=0;
if (x>document.slIderRailLength) x=document.slIderRailLength;
document.getElementById(document.slIderName+"_divslider").style.left=x;
}
document.slIderstartDX=(x+absX0)-parseInt(document.getElementById(document.slIderName+"_divslider").style.left)+document.slIderRailLeft;
document.slIderDragging=true;
mousemoveProcess(e);
}
}
}
function slIderMousemoveProcess(e) {
var x=e.pageX-document.slIderstartDX;
if (document.slIderstartFine>=0) x= (document.slIderFine*document.slIderstartFine+x)/(document.slIderFine+1);
if (x<0) x=0;
if (x>document.slIderRailLength) x=document.slIderRailLength;
document.getElementById(document.slIderName+"_divslider").style.left=Math.round(x);
document.getElementById(document.slIderName+"_sliderValue").value= x /
(parseInt(document.getElementById(document.slIderName+"_slider").style.width)-
parseInt(document.getElementById(document.slIderName+"_divslider").style.width)); // (v =0..1)
setSliderText(document.slIderName); // from internal value set above
sliderActOnChange (document.slIderName);
}
function slIderMouseupProcess(e) {
sliderActOnDone (document.slIderName);
}
/*
* Here is how slider calls external functions when the slider is "done" (mouse button released) or "changed" (moved ).
* Changing the text field value also triggers function on "done"
*/
// action will not be performed if no changes since last external write to or same data was already sent out (does not matter - on change or on done)
function sliderActOnDone (id) {
var act= document.getElementById(id+"_actionOnDone").value;
// document.title+="?"+document.getElementById(id+"_forceUpdate").value; // (was set externally or already sent out)
if (act && ((document.getElementById(id+"_lastValueSet").value!=document.getElementById(id+"_sliderValue").value) ||
(document.getElementById(id+"_forceUpdate").value !=0))) {
eval (act);
document.getElementById(id+"_lastValueSet").value=document.getElementById(id+"_sliderValue").value; // to prevent triggering "onDone" "onChange" if the data did not change
document.getElementById(id+"_forceUpdate").value=0;
}
}
function sliderActOnChange (id) {
// document.title+="??"+document.getElementById(id+"_forceUpdate").value; //
var act= document.getElementById(id+"_actionOnChange").value;
if (act && ((document.getElementById(id+"_lastValueSet").value!=document.getElementById(id+"_sliderValue").value) ||
(document.getElementById(id+"_forceUpdate").value !=0))){
eval (act);
document.getElementById(id+"_lastValueSet").value=document.getElementById(id+"_sliderValue").value; // to prevent triggering "onDone" "onChange" if the data did not change
document.getElementById(id+"_forceUpdate").value=0;
}
}
function sliderActOnDoubleclick (id) {
var act= document.getElementById(id+"_actionOnDoubleclick").value;
if (act) eval (act);
}
/*
* process pressing on slider button
*/
function slIderButtonMouse(id,state,event) {
if (typeof(event)!="undefined") event.preventDefault();
slIderSetButtonState(id,state);
if (id.indexOf("slIder")>=0) {
id=id.substr(0,id.indexOf("slIder"))+"slIder";
var act= document.getElementById(id+"_actionOnButton").value;
if ((state=="on") && act) eval (act);
}
return false;
}
function slIderSetButtonState(id,state) { // specify state: on/off
var zstr=document.getElementById(id).src;
document.getElementById(id).src = ((zstr.lastIndexOf("_press")<0)?
(zstr.substr(0,zstr.lastIndexOf("."))):
(zstr.substr(0,zstr.lastIndexOf("_press")))) +
((state=="on")?"_press":"") +
zstr.substr(zstr.lastIndexOf("."));
}
/*
*! -----------------------------------------------------------------------------**
*! elphelTabs.js
*!
*! Copyright (C) 2006-2007 Elphel, Inc.
*!
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: elphelTabs.js,v $
*! Revision 1.1.1.1 2008/11/27 20:04:03 elphel
*!
*!
*! Revision 1.1.1.1 2007/09/19 04:51:17 elphel
*! This is a fresh tree based on elphel353-2.10
*!
*! Revision 1.2 2007/09/19 04:51:17 elphel
*! Upgraded license (header)
*!
*!
*/
/*
Two functions are used to manipulate tabs.
One - creates them, the other changes transparency
function createTabs ( id, // parent DIV id - dimensions will be used for other elements
bhw, // border image half width (full width for the rightmost and leftmost tab sides)
tabs_array, // each element is {url:"header_image_in_tabs",id:"div_id_to_show"}
tabs_img_pref, // prefix for all the tabs borders
tabs_img_suff, // suffix for all the tabs borders (normally just ".png"
tabs_shape,
tabs_onChange, // function to call when tabs are changed (i.e redraw screen to adjust to new dimensions)
tabs_resize) // if true, will resize the height of the parent element when the tabs are changed
There should be multuiple images prepare to use with the tabs. they may have different prefixes and suffixes, the middle parts are
as following (bhw - is half-width of the border between 2 tabs):
_left_sel - image of the left side of the leftmost tab when the tab is selected (width= bhw)
_left_unsel - image of the left side of the leftmost tab when the tab is not selected (width= bhw)
_right_sel - image of the right side of the rightmost tab when the tab is selected (width= bhw)
_right_unsel - image of the right side of the rightmost tab when the tab is not selected (width= bhw)
_sel - image of the middle of the tab header when the tab is selected - width= 1px usually, will be spread over the middle part of the tab header
_unsel - same when the tab us not selected
_sel_unsel - border between selected tab (to the left) and unselected tab (to the right)- width=2*bhw
_unsel_sel - border between unselected tab (to the left) and selected tab (to the right)- width=2*bhw
_unsel_unsel - border between two unselected tabs - width=2*bhw
Example: with following files:
images/tabs16x24_left_sel.png (8x24)
images/tabs16x24_left_unsel.png (8x24)
images/tabs16x24_right_sel.png (8x24)
images/tabs16x24_right_unsel.png (8x24)
images/tabs16x24_sel.png (1x24)
images/tabs16x24_unsel.png (1x24)
images/tabs16x24_sel_unsel.png (16x24)
images/tabs16x24_unsel_sel.png (16x24)
images/tabs16x24_unsel_unsel.png (16x24)
tabs_img_pref="images/tabs16x24"
tabs_img_suff=".png"
bhw=8
and tabs_shape is an 8-element array (same as bhw) taat describes the shape of the tabs borders ("t" - top, "b" - bottom, counted from the top of the image)
({b:21,t:1},{b:21,t:2},{b:20,t:2},{b:20,t:3},{b:19,t:4},{b:17,t:6},{b:15,t:8},{b:13,t:10})
The create Tabs function receives the DIV element ID that is designated for the tabs headers, each tab data is provided in an array of records with the following fields:
{url:"image_to_show_in_the_tab_header", - this image will be centered in the tab header
id:"DIV_element_ID_ for_the_tab_body", - ID of the tab itself that will be shown when the tab is opened
bg:"dddd88"}, - color of the tab (there should be semi-transparent 1x1 pixel images available for each color and each transparency used
The next function will set the colors to match transparency value. for each color and transparency value (except 0% and 100%) there should be 1x1 semi-transparent png image with the name:
<prefix>_RRGGBB_<opacity_in_percents=100-transparency>.png
function setTabsTransparency(tID,transp, prefix);
document.webcamsTabsShape=new Array ({b:21,t:1},{b:21,t:2},{b:20,t:2},{b:20,t:3},{b:19,t:4},{b:17,t:6},{b:15,t:8},{b:13,t:10});
function initAllTabs() {
createTabs ("idNetworkTabs",
8,
document.webcamsTabs,
"images/tabs16x24",
".png",
document.webcamsTabsShape);
}
*/
function createTabs ( id, // parent DIV id - dimensions will be used for other elements
bhw, // border image half width (full width for the rightmost and leftmost tab sides)
tabs_array, // each element is {url:"header_image_in_tabs",id:"div_id_to_show"}
tabs_img_pref, // prefix for all the tabs borders
tabs_img_suff, // suffix for all the tabs borders (normally just ".png"
tabs_shape,
tabs_onChange, // function to call when tabs are changed (i.e redraw screen to adjust to new dimensions)
tabs_resize // if true, will resize the height of the parent element when the tabs are changed
){
var w= parseInt(document.getElementById(id).style.width);
var h= parseInt(document.getElementById(id).style.height);
var n= tabs_array.length;
var s="";
var l=0;
var miw;
var l1;
var dbgl;
var i,j,t,b;
for (i=0;i<n;i++) {
dbgl=s.length;
l1=l;
if (i==0) {
s+='<div id="'+id+'_lu" style="position:absolute; left:0; top:0; width:'+bhw+'; height:'+h+'">\n';
for (j=0;j<bhw;j++) {
t=tabs_shape[bhw-1-j].t;
s+='<div id="'+id+'_lu'+j+'" style="position:absolute; left:'+j+'; top:'+t+';width:1; height:'+(h-t)+';"><!-'+'- -'+'-></div>\n';
}
s+= '<div style="position:absolute; top:0;left:0; width:'+bhw+';height:'+h+';"/>\n';
s+= '<img src="'+tabs_img_pref+'_left_unsel'+tabs_img_suff+'" style="width:'+bhw+';height:'+h+';"/>\n';
s+= '</div>\n';
s+= '</div>\n';
s+='<div id="'+id+'_ls" style="position:absolute; left:0; top:0; width:'+bhw+'; height:'+h+'">\n';
for (j=0;j<bhw;j++) { t=tabs_shape[bhw-1-j].t;
s+='<div id="'+id+'_ls'+j+'" style="position:absolute; left:'+j+'; top:'+t+';width:1; height:'+(h-t)+';"><!-'+'- -'+'-></div>\n';
}
s+='<div style="position:absolute; top:0;left:0; width:'+bhw+';height:'+h+';"/>\n';
s+= '<img src="'+tabs_img_pref+'_left_sel'+tabs_img_suff+'" style="width:'+bhw+';height:'+h+';"/>\n'+
'</div>\n';
s+= '</div>\n';
}
l+=bhw;
miw= Math.round(w*(i+1)/n)-l-bhw;
s+= '<div id="'+id+'_'+i+'u" style="position:absolute; left:'+l+'; top:0; width:'+miw+'; height:'+h+';">\n'+
'<img src="'+tabs_img_pref+'_unsel'+tabs_img_suff+'" style="width:'+miw+';height:'+h+'"/>\n'+
'</div>\n'+
'<div id="'+id+'_'+i+'s" style="position:absolute; left:'+l+'; top:0; width:'+miw+'; height:'+h+';">\n'+
'<img src="'+tabs_img_pref+'_sel'+tabs_img_suff+'" style="width:'+miw+';height:'+h+'"/>\n'+
'</div>\n';
l+=miw;
if (i<(n-1)) {
s+='<div id="'+id+'_'+i+'uu" style="position:absolute; left:'+l+'; top:0; width:'+(2*bhw)+'; height:'+h+'">\n';
for (j=0;j<2*bhw;j++) {t=(j>=bhw)?(tabs_shape[2*bhw-1-j].b):(tabs_shape[j].t);
s+='<div id="'+id+'_'+i+'uu'+j+'" style="position:absolute; left:'+j+'; top:'+t+';width:1; height:'+(h-t)+'"><!-'+'- -'+'-></div>\n';
}
for (j=0;j<bhw;j++) {t= tabs_shape[bhw-1-j].t; b=tabs_shape[bhw-1-j].b;
s+='<div id="'+id+'_'+i+'uu'+(j+2*bhw)+'" style="position:absolute; left:'+(j+bhw)+'; top:'+t+';width:1; height:'+(b-t)+'"><!-'+'- -'+'-></div>\n';
}
s+= '<div style="position:absolute; top:0;left:0; width:'+(2*bhw)+';height:'+h+';"/>\n';
s+= '<img src="'+tabs_img_pref+'_unsel_unsel'+tabs_img_suff+'" style="width:'+(2*bhw)+';height:'+h+'"/>\n';
s+= '</div>\n';
s+= '</div>\n';
s+='<div id="'+id+'_'+i+'su" style="position:absolute; left:'+l+'; top:0; width:'+(2*bhw)+'; height:'+h+'">\n';
for (j=0;j<2*bhw;j++) {t=(j>=bhw)?(tabs_shape[2*bhw-1-j].b):(tabs_shape[j].t);
s+='<div id="'+id+'_'+i+'su'+j+'" style="position:absolute; left:'+j+'; top:'+t+';width:1; height:'+(h-t)+'"><!-'+'- -'+'-></div>\n';
}
for (j=0;j<bhw;j++) {t= tabs_shape[bhw-1-j].t; b=tabs_shape[bhw-1-j].b;
s+='<div id="'+id+'_'+i+'su'+(j+2*bhw)+'" style="position:absolute; left:'+(j+bhw)+'; top:'+t+';width:1; height:'+(b-t)+'"><!-'+'- -'+'-></div>\n';
}
s+= '<div style="position:absolute; top:0;left:0; width:'+(2*bhw)+';height:'+h+';"/>\n';
s+= '<img src="'+tabs_img_pref+'_sel_unsel'+tabs_img_suff+'" style="width:'+(2*bhw)+';height:'+h+'"/>\n';
s+= '</div>\n';
s+= '</div>\n';
s+='<div id="'+id+'_'+i+'us" style="position:absolute; left:'+l+'; top:0; width:'+(2*bhw)+'; height:'+h+'">\n';
for (j=0;j<2*bhw;j++) {t=(j>=bhw)?(tabs_shape[2*bhw-1-j].t):(tabs_shape[j].b);
s+='<div id="'+id+'_'+i+'us'+j+'" style="position:absolute; left:'+j+'; top:'+t+';width:1; height:'+(h-t)+'"><!-'+'- -'+'-></div>\n';
}
for (j=0;j<bhw;j++) {t= tabs_shape[j].t; b=tabs_shape[j].b;
s+='<div id="'+id+'_'+i+'us'+(j+2*bhw)+'" style="position:absolute; left:'+j+'; top:'+t+';width:1; height:'+(b-t)+'"><!-'+'- -'+'-></div>\n';
}
s+= '<div style="position:absolute; top:0;left:0; width:'+(2*bhw)+';height:'+h+';"/>\n';
s+='<img src="'+tabs_img_pref+'_unsel_sel'+tabs_img_suff+'" style="width:'+(2*bhw)+';height:'+h+'"/>\n';
s+= '</div>\n';
s+= '</div>\n';
} else { //last tab
s+='<div id="'+id+'_ru" style="position:absolute; left:'+l+'; top:0; width:'+bhw+'; height:'+h+'">\n';
for (j=0;j<bhw;j++) { t=tabs_shape[j].t;
s+='<div id="'+id+'_ru'+j+'" style="position:absolute; left:'+j+'; top:'+t+';width:1; height:'+(h-t)+'"><!-'+'- -'+'-></div>\n';
}
s+= '<div style="position:absolute; top:0;left:0; width:'+bhw+';height:'+h+';"/>\n';
s+= '<img src="'+tabs_img_pref+'_right_unsel'+tabs_img_suff+'" style="width:'+bhw+';height:'+h+'"/>\n';
s+= '</div>\n';
s+= '</div>\n';
s+='<div id="'+id+'_rs" style="position:absolute; left:'+l+'; top:0; width:'+bhw+'; height:'+h+'">\n';
for (j=0;j<bhw;j++) { t=tabs_shape[j].t;
s+='<div id="'+id+'_rs'+j+'" style="position:absolute; left:'+j+'; top:'+t+';width:1; height:'+(h-t)+'"><!-'+'- -'+'-></div>\n';
}
s+= '<div style="position:absolute; top:0;left:0; width:'+bhw+';height:'+h+';"/>\n';
s+= '<img src="'+tabs_img_pref+'_right_sel'+tabs_img_suff+'" style="width:'+bhw+';height:'+h+'"/>\n';
s+= '</div>\n';
s+= '</div>\n';
}
l+=bhw;
if (tabs_array[i].url.substr(0,1)=="*") { // test title
s+='<div id="'+id+'_'+i+'t" style="text-align: center; position:absolute; left:'+l1+'; top:4; width:'+(l-l1)+'; height:'+h+';" onclick="onClickTabs('+"'"+id+"',"+i+');"/>\n'+
tabs_array[i].url.substr(1)+'</div>\n'; // needs something to be in the div (comments OK). Split html comments tags to escape them if this code will be in html file.
} else {
s+='<div id="'+id+'_'+i+'t" style="position:absolute; left:'+l1+'; top:0; width:'+(l-l1)+'; height:'+h+
'; background-image: url('+tabs_array[i].url+'); background-repeat:no-repeat; background-position: center center;" onclick="onClickTabs('+"'"+id+"',"+i+');"/>\n'+
'<!-'+'- -'+'-></div>\n'; // needs something to be in the div (comments OK). Split html comments tags to escape them if this code will be in html file.
}
s+='<input type="hidden" id="'+id+'_'+i+'hi" value="'+ tabs_array[i].id +'"/>\n';
s+='<input type="hidden" id="'+id+'_'+i+'bg" value="'+ tabs_array[i].bg +'"/>\n';
//alert ("i="+i+" l1="+l1+" miw="+miw+" l="+l);
//alert(s.substr(dbgl,s.length-dbgl));
}
s+='<input type="hidden" id="'+id+'_numberOfTabs" value="'+ tabs_array.length +'"/>\n';
s+='<input type="hidden" id="'+id+'_selected" value="-1"/>\n';
s+='<input type="hidden" id="'+id+'_bhw" value="'+ bhw +'"/>\n';
s+='<input type="hidden" id="'+id+'_chng" value="'+ tabs_onChange +'"/>\n';
s+='<input type="hidden" id="'+id+'_resize" value="'+ (tabs_resize?"1":"")+'"/>\n';
document.getElementById(id).innerHTML=s;
onClickTabs(id,0,n,tabs_array[0].id);
}
// will set the colors to match transparency value. for each color and transparency value (except 0% and 100%) there should be 1x1 semi-transparent png image with the name:
// <prefix>_RRGGBB_<opacity_in_percents=100-transparency>.png
function setTabsTransparency(tID,transp, prefix) {
var i,j;
var dID;
var bg;
var bgImg;
var isTransparent= (transp>0);
var noBgImage= (transp==100) || !isTransparent;
if (!document.getElementById(tID+'_numberOfTabs')) return; // if this is called before tabs are created
var nTab=parseInt(document.getElementById(tID+'_numberOfTabs').value);
var bhw= parseInt(document.getElementById(tID+'_bhw').value);
for (i=0;i<nTab;i++) {
dID=document.getElementById(tID+'_'+i+'hi').value;
bg=document.getElementById(tID+'_'+i+'bg').value;
bgImg="url("+prefix+bg+"_"+(100-transp)+".png)";
bg="#"+bg;
// tab pages
document.getElementById(dID).style.backgroundColor=isTransparent?"":bg;
document.getElementById(dID).style.backgroundImage=noBgImage?"":bgImg;
// tab middle sections
document.getElementById(tID+'_'+i+'u').style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_'+i+'u').style.backgroundImage=noBgImage?"":bgImg;
document.getElementById(tID+'_'+i+'s').style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_'+i+'s').style.backgroundImage=noBgImage?"":bgImg;
// left sides of the leftmost tab
if (i==0) {
for (j=0;j<bhw;j++) {
if (document.getElementById(tID+'_lu'+j)) document.getElementById(tID+'_lu'+j).style.backgroundColor=isTransparent?"":bg;
if (document.getElementById(tID+'_lu'+j)) document.getElementById(tID+'_lu'+j).style.backgroundImage=noBgImage?"":bgImg;
document.getElementById(tID+'_ls'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_ls'+j).style.backgroundImage=noBgImage?"":bgImg;
}
} else {
//left side of other (not the leftmost) tabs
for (j=2*bhw;j<3*bhw;j++) {
document.getElementById(tID+'_'+(i-1)+'uu'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_'+(i-1)+'uu'+j).style.backgroundImage=noBgImage?"":bgImg;
document.getElementById(tID+'_'+(i-1)+'su'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_'+(i-1)+'su'+j).style.backgroundImage=noBgImage?"":bgImg;
}
for (j=0;j<2*bhw;j++) {
document.getElementById(tID+'_'+(i-1)+'us'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_'+(i-1)+'us'+j).style.backgroundImage=noBgImage?"":bgImg;
}
}
// right sides of the leftmost tab
if (i==(nTab-1)) {
for (j=0;j<bhw;j++) {
document.getElementById(tID+'_ru'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_ru'+j).style.backgroundImage=noBgImage?"":bgImg;
document.getElementById(tID+'_rs'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_rs'+j).style.backgroundImage=noBgImage?"":bgImg;
}
} else {
//right side of other (not the rightmost) tabs
for (j=0;j<2*bhw;j++) {
document.getElementById(tID+'_'+i+'uu'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_'+i+'uu'+j).style.backgroundImage=noBgImage?"":bgImg;
document.getElementById(tID+'_'+i+'su'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_'+i+'su'+j).style.backgroundImage=noBgImage?"":bgImg;
}
for (j=2*bhw;j<3*bhw;j++) {
document.getElementById(tID+'_'+i+'us'+j).style.backgroundColor=isTransparent?"":bg;
document.getElementById(tID+'_'+i+'us'+j).style.backgroundImage=noBgImage?"":bgImg;
}
}
}
}
/*
function isShownTabs(tID,iTab) {
// try to see if it is visible regardless of what hides it (
}
*/
function onClickTabs(tID,iTab) {
// alert ("tID="+tID+" iTab="+iTab);
var dID;
//document.title="tID="+tID+" iTab="+iTab;
var nTab=parseInt(document.getElementById(tID+'_numberOfTabs').value);
if (!((iTab>=0) && (iTab <nTab))) iTab=-1; // no tabs open
for (i=0; i< nTab; i++) {
dID=document.getElementById(tID+'_'+i+'hi').value;
document.getElementById(dID).style.display=(i==iTab)?"":"none";
if (i==iTab) {
if (i==0) {
document.getElementById(tID+'_lu').style.display="none";
document.getElementById(tID+'_ls').style.display="";
}
document.getElementById(tID+'_'+i+'u').style.display="none";
document.getElementById(tID+'_'+i+'s').style.display="";
if (i<(nTab-1)) {
document.getElementById(tID+'_'+i+'uu').style.display="none";
document.getElementById(tID+'_'+i+'us').style.display="none";
document.getElementById(tID+'_'+i+'su').style.display="";
} else {
document.getElementById(tID+'_ru').style.display="none";
document.getElementById(tID+'_rs').style.display="";
}
}else {
if (i==0) {
document.getElementById(tID+'_lu').style.display="";
document.getElementById(tID+'_ls').style.display="none";
}
document.getElementById(tID+'_'+i+'u').style.display="";
document.getElementById(tID+'_'+i+'s').style.display="none";
if (i<(nTab-1)) {
document.getElementById(tID+'_'+i+'uu').style.display=(i==(iTab-1))?"none":"";
document.getElementById(tID+'_'+i+'us').style.display=(i==(iTab-1))?"":"none";
document.getElementById(tID+'_'+i+'su').style.display="none";
} else {
document.getElementById(tID+'_ru').style.display="";
document.getElementById(tID+'_rs').style.display="none";
}
}
}
if (document.getElementById(tID+'_resize').value) {
// adjust the parent height to the height of the current tab
// maybe use offsetParent, not parentNode?
// offsetHeight works only if element is actually visible !!!
// (iTab<0) if no tab is selected - use only the header
document.getElementById(tID).parentNode.style.height=(parseInt(document.getElementById(tID).style.height) +
((iTab>=0)?parseInt(document.getElementById(document.getElementById(tID+'_'+iTab+'hi').value).offsetHeight):0))+"px";
//alert ("tID="+tID+" iTab="+iTab+" height="+ (parseInt(document.getElementById(tID).style.height) + ((iTab>=0)?parseInt(document.getElementById(document.getElementById(tID+'_'+iTab+'hi').value).offsetHeight):0))+"px");
}
document.getElementById(tID+'_selected').value=iTab;
if (document.getElementById(tID+'_chng').value) eval (document.getElementById(tID+'_chng').value);
}
function getSelectedTab(tID) {
return parseInt(document.getElementById(tID+'_selected').value);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment