git-svn-id: https://svn.fhem.de/fhem/trunk@3162 2b470e98-0d58-463d-a4d8-8e2adae1ed80
416
fhem/contrib/YAF/01_YAF.pm
Normal file
@ -0,0 +1,416 @@
|
||||
########################################################################################
|
||||
#
|
||||
# 01_YAF.pm
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee, Prof. Dr. Peter A. Henning
|
||||
#
|
||||
# $Id: 01_YAF.pm 2013-05 - pahenning $
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
package main;
|
||||
|
||||
use JSON::XS;
|
||||
use strict;
|
||||
use warnings;
|
||||
use lib qw(YAF);
|
||||
use YAF::YAFWidgets;
|
||||
use YAF::YAFConfig;
|
||||
|
||||
use vars qw(%data);
|
||||
use vars qw(%_GET);
|
||||
use vars qw(%defs);
|
||||
use vars qw($FW_cname);
|
||||
use vars qw($FW_RET);
|
||||
use vars qw($FW_dir);
|
||||
|
||||
sub YAF_Request($@);
|
||||
|
||||
my $fhem_url;
|
||||
my $yaf_version=0.41;
|
||||
my $yafw_encoding = "UTF-8";
|
||||
my $mp = AttrVal("global", "modpath", ".");
|
||||
my $yaf_www_directory = $mp."/FHEM/YAF/www";
|
||||
|
||||
YAF_Config();
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# YAF_Initialize - register YAF with FHEM
|
||||
#
|
||||
# Parameter hash
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_Initialize ($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{DefFn} = "YAF_define";
|
||||
|
||||
my $name = "YAF";
|
||||
$fhem_url = "/" . $name;
|
||||
$data{FWEXT}{$fhem_url}{FUNC} = "YAF_Request";
|
||||
$data{FWEXT}{$fhem_url}{LINK} = "YAF/www/global/yaf.htm";
|
||||
$data{FWEXT}{$fhem_url}{NAME} = "YAF";
|
||||
|
||||
#-- load widgets
|
||||
YAF_requireWidgets();
|
||||
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# YAF_Print
|
||||
#
|
||||
# Parameter hash
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_Print($@) {
|
||||
if ($_[0]) {
|
||||
$FW_RET .= $_[0];
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# YAF_Clean - clear output buffer
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_Clean() {
|
||||
$FW_RET = "";
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# YAF_LoadResource - Load a file from YAF directory
|
||||
#
|
||||
# Parameter hash
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_LoadResource($@) {
|
||||
my $absoluteFilePath = $_[0];
|
||||
|
||||
my $filebuffer = "";
|
||||
my $fh;
|
||||
|
||||
# Filename
|
||||
my @absoluteFilePathSplitted = split(/\//, $absoluteFilePath);
|
||||
my $filename = $absoluteFilePathSplitted[scalar(@absoluteFilePathSplitted)-1];
|
||||
|
||||
# Extension
|
||||
my @filenameSplitted = split(/\./, $filename);
|
||||
my $extension = $filenameSplitted[scalar(@filenameSplitted)-1];
|
||||
#Log 1,"YAF_LoadResource absoluteFilePath $absoluteFilePath filename $filename extension $extension";
|
||||
|
||||
# Datei laden
|
||||
if ((-f $absoluteFilePath) && open($fh, "<", $absoluteFilePath)) {
|
||||
binmode $fh;
|
||||
my ($data, $n);
|
||||
while (($n = read $fh, $data, 4) != 0) {
|
||||
$filebuffer .= $data;
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Datei nicht gefunden
|
||||
Log 1,"YAF_LoadResource: file $filename not found";
|
||||
return YAF_NotFound($absoluteFilePath);
|
||||
}
|
||||
close($fh);
|
||||
|
||||
if ($extension eq "htm" || $extension eq "html") {
|
||||
if ($filename eq "yaf.htm") {
|
||||
# replace:
|
||||
# ###widget_css###
|
||||
# ###widget_js###
|
||||
my $widget_css = YAF_getWidgetsCss();
|
||||
my $widget_js = YAF_getWidgetsJs();
|
||||
$filebuffer =~ s/###widget_css###/$widget_css/g;
|
||||
$filebuffer =~ s/###widget_js###/$widget_js/g;
|
||||
}
|
||||
YAF_Print($filebuffer);
|
||||
return ("text/html; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
elsif ($extension eq "gif") {
|
||||
YAF_Print($filebuffer);
|
||||
return ("image/gif; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
elsif ($extension eq "jpg" || $extension eq "jpeg") {
|
||||
YAF_Print($filebuffer);
|
||||
return ("image/jpeg; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
elsif ($extension eq "png") {
|
||||
YAF_Print($filebuffer);
|
||||
return ("image/png; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
elsif ($extension eq "css") {
|
||||
YAF_Print($filebuffer);
|
||||
return ("text/css; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
elsif ($extension eq "js") {
|
||||
YAF_Print($filebuffer);
|
||||
return ("text/javascript; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
else {
|
||||
YAF_Print($filebuffer);
|
||||
return ("text/plain; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# YAF_define
|
||||
#
|
||||
# Parameter hash
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_define ($@) {
|
||||
my ($hash, $def) = @_;
|
||||
return;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# YAF_LoadView
|
||||
#
|
||||
# Parameter hash
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_LoadView($@) {
|
||||
my ($view) = @_;
|
||||
YAF_Print("ddd");
|
||||
return ("text/html; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# YAF_Request - http://fhemurl:fhemport/YAF is processed here
|
||||
#
|
||||
# Parameter hash, request-string
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_Request ($@) {
|
||||
my ($htmlarg) = @_;
|
||||
# %20 durch Leerzeichen ersetzen
|
||||
$htmlarg =~ s/%20/ /g;
|
||||
|
||||
# GET Parameter
|
||||
my @params = split(/\?/, $htmlarg);
|
||||
|
||||
if (scalar(@params) > 1) {
|
||||
my @attributesArray = split("&",$params[1]);
|
||||
my @attributePair;
|
||||
for (my $i = 0; $i < scalar(@attributesArray); $i++) {
|
||||
@attributePair = split("=",$attributesArray[$i]);
|
||||
$_GET{$attributePair[0]} = $attributePair[1];
|
||||
}
|
||||
}
|
||||
|
||||
@params = split(/\//, $params[0]);
|
||||
|
||||
#-- clean output buffer
|
||||
YAF_Clean();
|
||||
|
||||
#-- take URI apart
|
||||
my $controler_count = scalar(@params);
|
||||
#Log 1,"YAF_Request: arguments $htmlarg params ".join(' ',@params);
|
||||
|
||||
#-- examples are
|
||||
#/YAF/global/yaf.htm
|
||||
#/YAF/global/js/yaf-dialogs.js
|
||||
#/YAF/ajax/global/getRefreshTime
|
||||
|
||||
my $control_1 = $params[1];
|
||||
my $control_2 = $params[2];
|
||||
my $control_3 = $params[3];
|
||||
|
||||
if ($controler_count > 3) {
|
||||
#-- either global, widget or ajax
|
||||
if ($control_2 eq "global") {
|
||||
my $request_file = $yaf_www_directory;
|
||||
my $pos = 3;
|
||||
for (; $pos < scalar(@params); $pos++) {
|
||||
$request_file .= "/";
|
||||
$request_file .= $params[$pos];
|
||||
}
|
||||
# Resource aus dem global www Verzeichnis laden
|
||||
return YAF_LoadResource($request_file);
|
||||
}
|
||||
elsif ($control_2 eq "widget") {
|
||||
return ("text/plain; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
elsif ($control_2 eq "ajax") {
|
||||
if ($control_3 eq "global") {
|
||||
if ($controler_count > 4) {
|
||||
my $function = "";
|
||||
$function = $params[4];
|
||||
if ($function eq "getViews") {
|
||||
my $views = encode_json(YAF_getViews());
|
||||
YAF_Print($views);
|
||||
}
|
||||
#-- adds a View
|
||||
elsif ($function eq "addView") {
|
||||
if ($_GET{"name"} && (YAF_addView($_GET{"name"}) == 1)) {
|
||||
YAF_Print("1");
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
#-- deletes a View
|
||||
elsif ($function eq "deleteView") {
|
||||
if ($_GET{"id"} && (YAF_deleteView($_GET{"id"}) == 1)) {
|
||||
YAF_Print("1");
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
#-- returns all Widgets of a View
|
||||
elsif ($function eq "getView") {
|
||||
if ($_GET{"id"}) {
|
||||
YAF_Print(encode_json(YAF_getView($_GET{"id"})));
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
#-- changes the name of a View
|
||||
elsif ($function eq "editView") {
|
||||
if ($_GET{"id"} && $_GET{"name"}) {
|
||||
YAF_Print(YAF_editView($_GET{"id"}, $_GET{"name"}));
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
#-- modify position of a Widget
|
||||
elsif ($function eq "setWidgetPosition") {
|
||||
if ($_GET{"view_id"} && $_GET{"widget_id"} && $_GET{"x_pos"} && $_GET{"y_pos"}) {
|
||||
YAF_setWidgetPosition($_GET{"view_id"}, $_GET{"widget_id"}, $_GET{"x_pos"}, $_GET{"y_pos"});
|
||||
YAF_Print("1");
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
#-- get Widgets
|
||||
elsif ($function eq "getWidgets") {
|
||||
my @widgets = YAF_getWidgetArray();
|
||||
YAF_Print(encode_json(\@widgets));
|
||||
}
|
||||
#-- add Widget
|
||||
elsif ($function eq "addWidget") {
|
||||
if ($_GET{"view_id"} && $_GET{"widget"} && $_GET{"attributes"}) {
|
||||
# %22 wieder durch " ersetzen!
|
||||
# @TODO Probleme mit Sonderzeichen müssen noch behoben werden!
|
||||
$_GET{"attributes"} =~ s/%22/"/g;
|
||||
my @attributes_array = @{decode_json($_GET{"attributes"})};
|
||||
my $widgetId = YAF_addWidget($_GET{"view_id"},$_GET{"widget"}, 28, 69, \@attributes_array);
|
||||
YAF_Print($widgetId);
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
#-- delete Widget
|
||||
elsif($function eq "deleteWidget"){
|
||||
if ($_GET{"view_id"} && $_GET{"widget_id"} && (YAF_deleteWidget($_GET{"view_id"}, $_GET{"widget_id"}) == 1)) {
|
||||
YAF_Print("1");
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
#-- get RefreshTime
|
||||
elsif($function eq "getRefreshTime"){
|
||||
my $refreshTime = YAF_getRefreshTime();
|
||||
YAF_Print($refreshTime);
|
||||
}
|
||||
#-- set RefreshTime
|
||||
elsif($function eq "setRefreshTime"){
|
||||
if($_GET{"interval"}){
|
||||
my $newRefreshTime = $_GET{"interval"};
|
||||
YAF_setRefreshTime($newRefreshTime);
|
||||
YAF_Print($newRefreshTime);
|
||||
} else{
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
}
|
||||
else {
|
||||
YAF_Print("1");
|
||||
}
|
||||
return ("text/plain; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
#-- evaluation of a widget function
|
||||
elsif ($control_3 eq "widget") {
|
||||
my $widget = $params[4];
|
||||
my $function = $params[5];
|
||||
if ($widget ne "") {
|
||||
YAF_Print(eval($widget."_".$function."();")) or YAF_Print("0");
|
||||
}
|
||||
else {
|
||||
YAF_Print("0");
|
||||
}
|
||||
#Log 1,"++++++++++++> Widget $widget called with function $function, length of return was ".length($FW_RET);
|
||||
return ("text/plain; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
else {
|
||||
Log 1,"YAF_Request: B response not found $control_1 $control_2";
|
||||
return YAF_NotFound($htmlarg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log 1,"YAF_Request: C response not found $control_1 $control_2";
|
||||
return YAF_NotFound($htmlarg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log 1,"YAF_Request: D response not found $control_1 $control_2";
|
||||
return YAF_NotFound($htmlarg);
|
||||
}
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# YAF_NotFound - Return a 404 Error
|
||||
#
|
||||
# Parameter hash, request-string
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_NotFound{
|
||||
my $file = $_[0];
|
||||
YAF_Print("Error 404: $file");
|
||||
YAF_Print("\n");
|
||||
return ("text/html; charset=$yafw_encoding", $FW_RET);
|
||||
}
|
||||
|
||||
1;
|
19
fhem/contrib/YAF/Makefile
Executable file
@ -0,0 +1,19 @@
|
||||
VERS=0.41
|
||||
DATE=2013-03-10
|
||||
|
||||
FHEMDIR=../../FHEM/fhem
|
||||
|
||||
all:
|
||||
@echo "Use make install to install YAF"
|
||||
|
||||
install:
|
||||
@echo "Installing YAF to FHEM installation in ${FHEMDIR}"
|
||||
@echo "- copying files"
|
||||
@cp 01_YAF.pm ${FHEMDIR}/FHEM
|
||||
@cp -rp YAF ${FHEMDIR}/FHEM
|
||||
@echo
|
||||
@echo "Installation of YAF completed!"
|
||||
@echo
|
||||
@echo "Do not forget to configure YAF in fhem.cfg with"
|
||||
@echo "define yaf YAF"
|
||||
@echo
|
26
fhem/contrib/YAF/README
Normal file
@ -0,0 +1,26 @@
|
||||
########################################################################################
|
||||
#
|
||||
# README
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
Please notice the installation guide included in the documentation.
|
507
fhem/contrib/YAF/YAF/YAFConfig.pm
Normal file
@ -0,0 +1,507 @@
|
||||
########################################################################################
|
||||
#
|
||||
# YAFConfig.pm - sub-module to read and interpret the configuration file
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee, Prof. Dr. Peter A. Henning
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use XML::LibXML;
|
||||
use XML::LibXML::PrettyPrint;
|
||||
|
||||
my $yaf_version=0.41;
|
||||
my $mp = AttrVal("global", "modpath", ".");
|
||||
my $configurationFilepath = $mp."/FHEM/YAF/xml/yafConfig.xml";
|
||||
my $schemaFilepath = $mp."/FHEM/YAF/xml/xmlSchema.xsd";
|
||||
my $xmlSchema;
|
||||
my $prettyPrinter;
|
||||
my $config;
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_Config - Initializes this module by creating the schema, pretty printer and
|
||||
# loading the configuration from the filepath
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_Config {
|
||||
$xmlSchema = XML::LibXML::Schema->new(location => $schemaFilepath);
|
||||
$prettyPrinter = XML::LibXML::PrettyPrint->new(indent_string => " ");
|
||||
$config = XML::LibXML->load_xml(location => $configurationFilepath);
|
||||
YAF_validate();
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_validate - Validates the current state of the configuration instance
|
||||
#
|
||||
# no parameter
|
||||
# Returns 1 if valid, otherwise 0.
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_validate{
|
||||
eval{ $xmlSchema->validate($config); };
|
||||
|
||||
if($@){
|
||||
Log 1,"YAF: error validating configuration file";
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_getViews - Assembles defined views from configuration file
|
||||
#
|
||||
# no parameter
|
||||
# Returns pointer to array of views.
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_getViews{
|
||||
my @views = $config->findnodes('//view');
|
||||
my @viewsArray;
|
||||
my $index = 0;
|
||||
|
||||
foreach my $view (@views){
|
||||
$viewsArray[$index][0] = $view->findvalue('@id');
|
||||
$viewsArray[$index][1] = $view->findvalue('@name');
|
||||
$index++;
|
||||
}
|
||||
|
||||
return \@viewsArray;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_getView - Assembles parts of a view from configuration file
|
||||
#
|
||||
# viewId - The view id to search
|
||||
# Returns Pointer to the view hash, hash may be empty
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_getView{
|
||||
my $viewId = $_[0];
|
||||
|
||||
my %viewHash = ();
|
||||
|
||||
#-- query view id
|
||||
my $viewResult = $config->findnodes('//view[@id = '.$viewId.']');
|
||||
if($viewResult->size() == 1){
|
||||
my $view = $viewResult->get_node(0);
|
||||
|
||||
#-- prepare view hash and add simple key/value pairs (name)
|
||||
$viewHash{'name'} = $view->findvalue('@name');
|
||||
|
||||
#-- collect all widgets and add them to an array which is then connected to the view hash
|
||||
my @widgetsArray = ();
|
||||
my @widgets = $view->findnodes('widgets/widget');
|
||||
|
||||
foreach my $widget (@widgets){
|
||||
my @attributes = $widget->attributes();
|
||||
my %widgetHash = ();
|
||||
|
||||
foreach my $attribute (@attributes){
|
||||
$widgetHash{$attribute->nodeName} = $attribute->getValue();
|
||||
}
|
||||
|
||||
#-- collect attr nodes in a hash and add to widget
|
||||
my %attrHash = ();
|
||||
my @attrs = $widget->getChildrenByTagName('attr');
|
||||
|
||||
foreach my $attr (@attrs){
|
||||
my $key = $attr->findvalue('@name');
|
||||
my $value = $attr->findvalue('@value');
|
||||
$attrHash{$key} = $value;
|
||||
}
|
||||
$widgetHash{'attr'} = \%attrHash;
|
||||
|
||||
|
||||
push(@widgetsArray, \%widgetHash);
|
||||
}
|
||||
$viewHash{'widgets'} = \@widgetsArray;
|
||||
|
||||
#-- collect all backgrounds and add them to an array which is then connected to the view hash
|
||||
my @backgroundsArray = ();
|
||||
my @backgrounds = $view->findnodes('backgrounds/background');
|
||||
|
||||
foreach my $background (@backgrounds){
|
||||
my @attributes = $background->attributes();
|
||||
my %backgroundHash = ();
|
||||
|
||||
foreach my $attribute (@attributes){
|
||||
$backgroundHash{$attribute->nodeName} = $attribute->getValue();
|
||||
}
|
||||
|
||||
push(@backgroundsArray, \%backgroundHash);
|
||||
}
|
||||
$viewHash{'backgrounds'} = \@backgroundsArray;
|
||||
} else{
|
||||
Log 1,"YAF_getView: view with id = ".$viewId." was not found";
|
||||
}
|
||||
|
||||
return \%viewHash;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_editView - Edits the view with the given id
|
||||
#
|
||||
# viewId - The view id to search
|
||||
# viewName The view name to be set
|
||||
# @return 1 if successful, otherwise 0
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_editView{
|
||||
my $viewId = $_[0];
|
||||
my $viewName = $_[1];
|
||||
|
||||
my $viewResult = $config->findnodes('//view[@id = '.$viewId.']');
|
||||
if($viewResult->size() == 1){
|
||||
my $view = $viewResult->get_node(0);
|
||||
$view->setAttribute('name', $viewName);
|
||||
YAF_saveConfiguration();
|
||||
return 1;
|
||||
} else {
|
||||
Log 1,"YAF_editView: view with id = ".$viewId." was not found";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_deleteView - Deletes the view with the given id
|
||||
#
|
||||
# viewId - The view id to search
|
||||
# @return 1 if successful, otherwise 0
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
sub YAF_deleteView{
|
||||
my $viewId = $_[0];
|
||||
|
||||
my $viewResult = $config->findnodes('//view[@id = '.$viewId.']');
|
||||
if($viewResult->size() == 1){
|
||||
my $view = $viewResult->get_node(0);
|
||||
my $views = $view->parentNode;
|
||||
$views->removeChild($view);
|
||||
YAF_saveConfiguration();
|
||||
return 1;
|
||||
} else{
|
||||
Log 1,"YAF_deleteView: view with id = ".$viewId." was not found";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_addView - Add the view with the given id
|
||||
#
|
||||
# viewId - The view id to search
|
||||
# @return 1 if successful, otherwise 0
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
sub YAF_addView{
|
||||
my $viewName = $_[0];
|
||||
|
||||
#-- determine id for new element
|
||||
my $newId = 0;
|
||||
my @views = $config->findnodes('//view');
|
||||
|
||||
foreach my $view (@views){
|
||||
my $tempId = $view->findvalue('@id');
|
||||
|
||||
if($newId < $tempId){
|
||||
$newId = $tempId;
|
||||
}
|
||||
}
|
||||
$newId++;
|
||||
|
||||
#-- initialize view and append to document
|
||||
my $view = $config->createElement('view');
|
||||
$view->setAttribute('id', $newId);
|
||||
$view->setAttribute('name', $viewName);
|
||||
#-- set default background
|
||||
my $backgrounds = $config->createElement('backgrounds');
|
||||
my $background = $config->createElement('background');
|
||||
$background->setAttribute('img_url', "./img/eg.jpeg");
|
||||
$background->setAttribute('x_pos', 1);
|
||||
$background->setAttribute('y_pos', 1);
|
||||
$backgrounds->appendChild($background);
|
||||
$view->appendChild($backgrounds);
|
||||
#-- initialize empty widgets node
|
||||
my $widgets = $config->createElement('widgets');
|
||||
$view->appendChild($widgets);
|
||||
|
||||
#-- add new view to configuration
|
||||
my $parent = $config->findnodes('//views')->get_node(0);
|
||||
$parent->appendChild($view);
|
||||
|
||||
YAF_saveConfiguration();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_addWidget - Add widget the the view with the given id
|
||||
#
|
||||
# Parameters:
|
||||
# widgetName The name of the new widget
|
||||
# xPos The x coordinate of the widget position
|
||||
# yPos The y coordinate of the widget position
|
||||
# attributesArray The array of attribute elements
|
||||
# @return The widget id if successful, otherwise 0
|
||||
#
|
||||
#########################################################################################
|
||||
|
||||
sub YAF_addWidget{
|
||||
my $viewId = $_[0];
|
||||
my $widgetName = $_[1];
|
||||
my $xPos = $_[2];
|
||||
my $yPos = $_[3];
|
||||
my @attributesArray = @{$_[4]};
|
||||
|
||||
my $viewsResult = $config->findnodes('//view[@id = '.$viewId.']');
|
||||
if($viewsResult->size() == 1){
|
||||
my $view = $viewsResult->get_node(0);
|
||||
|
||||
#-- create a new widget with given properties
|
||||
my $widget = $config->createElement('widget');
|
||||
$widget->setAttribute('name', $widgetName);
|
||||
$widget->setAttribute('x_pos', $xPos);
|
||||
$widget->setAttribute('y_pos', $yPos);
|
||||
my @widgets = $view->findnodes('widgets/widget');
|
||||
my $newId = 0;
|
||||
|
||||
foreach my $currentWidget (@widgets){
|
||||
my $tempId = $currentWidget->findvalue('@id');
|
||||
|
||||
if($newId < $tempId){
|
||||
$newId = $tempId;
|
||||
}
|
||||
}
|
||||
$newId++;
|
||||
$widget->setAttribute('id', $newId);
|
||||
|
||||
#-- add widgets attribute nodes
|
||||
foreach my $attribute (@attributesArray){
|
||||
my $attr = $config->createElement('attr');
|
||||
$attr->setAttribute('name', @$attribute[0]);
|
||||
$attr->setAttribute('value', @$attribute[1]);
|
||||
$widget->appendChild($attr);
|
||||
}
|
||||
|
||||
#-- append the new widget to the configuration
|
||||
my $widgetsNode = $view->findnodes('widgets')->get_node(0);
|
||||
$widgetsNode->appendChild($widget);
|
||||
|
||||
YAF_saveConfiguration();
|
||||
return $newId;
|
||||
} else{
|
||||
Log 1,"YAF_addWidget: view with id = ".$viewId." was not found";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_deleteWidget - Delete the Widget
|
||||
#
|
||||
# Parameters
|
||||
# viewId - The view id to search
|
||||
# widgetId - The widget id
|
||||
# @return 1 if successful, otherwise 0
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
sub YAF_deleteWidget{
|
||||
my $viewId = $_[0];
|
||||
my $widgetId = $_[1];
|
||||
|
||||
my $widgetResult = $config->findnodes('//view[@id = '.$viewId.']/widgets/widget[@id = '.$widgetId.']');
|
||||
if($widgetResult->size() == 1){
|
||||
my $widget = $widgetResult->get_node(0);
|
||||
my $widgets = $widget->parentNode;
|
||||
$widgets->removeChild($widget);
|
||||
|
||||
YAF_saveConfiguration();
|
||||
return 1;
|
||||
} else{
|
||||
Log 1,"YAF_deleteWidget: widget with id = ".$widgetId." in view with id = ".$viewId." was not found";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_isWidget - test, if a FHEM device name is already a widget
|
||||
#
|
||||
# viewId - The view id to search
|
||||
# fhemname - the name of a FHEM device
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_isWidget {
|
||||
my $viewId = $_[0];
|
||||
my $fhemname = $_[1];
|
||||
my $ret = 0;
|
||||
|
||||
my $widgetResult = $config->findnodes('//view[@id = '.$viewId.']/widgets/widget/attr[@value = "'.$fhemname.'"]');
|
||||
$ret = 1
|
||||
if($widgetResult->size() != 0);
|
||||
#Log 1,"YAF_isWidget: Checking with XPath //view[\@id = ".$viewId."]/widgets/widget/attr[\@value = \"".$fhemname."\"] => $ret";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_setWidgetPosition - Sets the position (x, y) of the widget to the given values
|
||||
#
|
||||
# Parameters
|
||||
# viewId - The view id to search
|
||||
# widgetId - The widget id
|
||||
# @param xPos The new x coordinate of the widget position
|
||||
# @param yPos The new y coordinate of the widget position
|
||||
# @return 1 if successful, otherwise 0
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
sub YAF_setWidgetPosition{
|
||||
my $viewId = $_[0];
|
||||
my $widgetId = $_[1];
|
||||
my $xPos = $_[2];
|
||||
my $yPos = $_[3];
|
||||
|
||||
my $widgetResult = $config->findnodes('//view[@id = '.$viewId.']/widgets/widget[@id = '.$widgetId.']');
|
||||
if($widgetResult->size() == 1){
|
||||
my $widget = $widgetResult->get_node(0);
|
||||
$widget->setAttribute('x_pos', $xPos);
|
||||
$widget->setAttribute('y_pos', $yPos);
|
||||
|
||||
YAF_saveConfiguration();
|
||||
return 1;
|
||||
} else{
|
||||
Log 1,"YAF_setWidgetPosition: widget with id = ".$widgetId." in view with id = ".$viewId." was not found";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_getWidgetAttribute - Searches the widget attribute properties of the specified widget
|
||||
#
|
||||
# Parameters
|
||||
# viewId - The view id to search
|
||||
# widgetId - The widget id
|
||||
# attributeName - name of the attribute properties to search for
|
||||
#
|
||||
# @return The value property if successful, otherwise 0
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
sub YAF_getWidgetAttribute{
|
||||
my $viewId = $_[0];
|
||||
my $widgetId = $_[1];
|
||||
my $attributeName = $_[2];
|
||||
|
||||
my $attributes = $config->findnodes('//view[@id = '.$viewId.']/widgets/widget[@id = '.$widgetId.']/attr');
|
||||
|
||||
foreach my $attr (@{$attributes}){
|
||||
if ($attr->getAttribute('name') eq $attributeName) {
|
||||
return $attr->getAttribute('value');
|
||||
}
|
||||
}
|
||||
Log 1,"YAF_getWidgetAttribute: attribute $attributeName was not found for widget with id = $widgetId";
|
||||
return 0;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_getRefreshTime - Get refresh time interval
|
||||
#
|
||||
# @return time successful, otherwise 0
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
sub YAF_getRefreshTime{
|
||||
my $refreshNodeResult = $config->findnodes('configuration/settings/refresh');
|
||||
if($refreshNodeResult->size() == 1){
|
||||
my $refreshNode = $refreshNodeResult->get_node(0);
|
||||
my $refreshTime = $refreshNode->getAttribute('interval');
|
||||
return $refreshTime;
|
||||
} else{
|
||||
Log 1,"YAF_getRefreshTime: refresh node was not found";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_setRefreshTime - Set refresh time interval to the given value
|
||||
# @return 1 if successful, otherwise 0
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
sub YAF_setRefreshTime{
|
||||
my $newRefreshInterval = $_[0];
|
||||
|
||||
my $refreshNodeResult = $config->findnodes('configuration/settings/refresh');
|
||||
if(($newRefreshInterval =~ /^\d+$/) && ($refreshNodeResult->size() == 1)){
|
||||
my $refreshNode = $refreshNodeResult->get_node(0);
|
||||
$refreshNode->setAttribute('interval', $newRefreshInterval);
|
||||
|
||||
YAF_saveConfiguration();
|
||||
return 1;
|
||||
} else{
|
||||
Log 1,"YAF_setRefreshTime: no valid refresh value or refresh node was not found";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_saveConfiguration - Save XML configuration file
|
||||
#
|
||||
# no parameter
|
||||
# @return 1 if successful, otherwise 0
|
||||
#
|
||||
#######################################################################################
|
||||
|
||||
sub YAF_saveConfiguration{
|
||||
my $state = 0;
|
||||
|
||||
if(YAF_validate() == 1){
|
||||
$prettyPrinter->pretty_print($config);
|
||||
$state = $config->toFile("$configurationFilepath");
|
||||
}
|
||||
return $state;
|
||||
}
|
||||
|
||||
1;
|
120
fhem/contrib/YAF/YAF/YAFWidgets.pm
Normal file
@ -0,0 +1,120 @@
|
||||
########################################################################################
|
||||
#
|
||||
# YAFWidgets.pm
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee, Prof. Dr. Peter A. Henning
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $yaf_version = 0.41;
|
||||
my $mp = AttrVal("global", "modpath", ".");
|
||||
my $yaf_dir = $mp."/FHEM/YAF/";
|
||||
my @yaf_widgets;
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_YAF_getWidgetArray
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_getWidgetArray() {
|
||||
@yaf_widgets = ();
|
||||
my $widgets_directory = $yaf_dir."widgets/";
|
||||
#-- open directory with widgets
|
||||
if( !opendir(DIR, $widgets_directory) ){
|
||||
Log 1,"YAF: directory with widgets not found";
|
||||
return undef;
|
||||
}
|
||||
my $is_dir = 0;
|
||||
#-- loop through all subdirectories
|
||||
while (my $entry = readdir DIR) {
|
||||
#-- check if it is really a directory
|
||||
if (-d $widgets_directory.$entry) {
|
||||
$is_dir = 1;
|
||||
#-- check for proper file widgetname.pm
|
||||
if (-e $widgets_directory.$entry."/".$entry.".pm") {
|
||||
$yaf_widgets[scalar(@yaf_widgets)] = $entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
#-- close directory
|
||||
closedir DIR;
|
||||
return @yaf_widgets;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_requireWidgets - load all widgets
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_requireWidgets() {
|
||||
YAF_getWidgetArray();
|
||||
foreach (@yaf_widgets){
|
||||
require($yaf_dir."widgets/".$_."/".$_.".pm");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_getWidgetsCss - assemble the CSS code of all widgets
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_getWidgetsCss() {
|
||||
my $output_widget_css = "";
|
||||
foreach (@yaf_widgets){
|
||||
my $widget_css = "";
|
||||
$widget_css = eval($_."_get_widgetcss();");
|
||||
$output_widget_css .= $widget_css;
|
||||
}
|
||||
return $output_widget_css;
|
||||
}
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# YAF_getWidgetsJs - assemble the JavaScript code of all widgets
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub YAF_getWidgetsJs() {
|
||||
my $output_widget_js = "";
|
||||
foreach (@yaf_widgets){
|
||||
my $widget_js = "";
|
||||
$widget_js = eval($_."_get_widgetjs();");
|
||||
$output_widget_js .= $widget_js;
|
||||
}
|
||||
return $output_widget_js;
|
||||
}
|
||||
|
||||
1;
|
228
fhem/contrib/YAF/YAF/widgets/fs20easylamp/fs20easylamp.pm
Normal file
@ -0,0 +1,228 @@
|
||||
########################################################################################
|
||||
#
|
||||
# fs20easylamp.pm
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee, Prof. Dr. Peter A. Henning
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $yaf_version = 0.41;
|
||||
|
||||
use vars qw(%_GET);
|
||||
use vars qw(%defs);
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# fs20easylamp_get_widgetcss - Create the CSS code for this widget
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20easylamp_get_widgetcss() {
|
||||
my $output = "
|
||||
.widget_fs20easylamp {
|
||||
width: 33px;
|
||||
height: 33px;
|
||||
background-repeat:no-repeat;
|
||||
background-position:center center;
|
||||
opacity:1 !important;
|
||||
}
|
||||
|
||||
.widget_fs20easylamp_on {
|
||||
background-image:url(./img/lamp_on.png) !important;
|
||||
}
|
||||
|
||||
.widget_fs20easylamp_off {
|
||||
background-image:url(./img/lamp_off.png) !important;
|
||||
}
|
||||
";
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20easylamp_get_widgetjs - Create the javascript code for this widget
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20easylamp_get_widgetjs() {
|
||||
|
||||
my $output = '
|
||||
function fs20easylamp_on_click(view_id, widget_id) {
|
||||
var widget = $("#widget_"+view_id+"_"+widget_id);
|
||||
var newState;
|
||||
if (widget.hasClass("widget_fs20easylamp_on")) {
|
||||
newState = "off";
|
||||
} else{
|
||||
newState = "on";
|
||||
}
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/widget/fs20easylamp/set_lamp_status",
|
||||
data: "view_id="+view_id+"&widget_id="+widget_id+"&status="+newState,
|
||||
context: document.body,
|
||||
success: function(){
|
||||
fs20easylamp_update_widget(view_id, widget_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fs20easylamp_update_widget(view_id, widget_id) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/widget/fs20easylamp/get_lamp_status",
|
||||
data: "view_id="+view_id+"&widget_id="+widget_id,
|
||||
context: document.body,
|
||||
success: function(lamp_status) {
|
||||
var widget = $("#widget_"+view_id+"_"+widget_id);
|
||||
if (lamp_status == "off") {
|
||||
if (widget.hasClass("widget_fs20easylamp_on")) {
|
||||
widget.removeClass("widget_fs20easylamp_on");
|
||||
}
|
||||
if (!widget.hasClass("widget_fs20easylamp_off")) {
|
||||
widget.addClass("widget_fs20easylamp_off");
|
||||
}
|
||||
}
|
||||
else if (lamp_status == "on") {
|
||||
if (!widget.hasClass("widget_fs20easylamp_on")) {
|
||||
widget.addClass("widget_fs20easylamp_on");
|
||||
}
|
||||
if (widget.hasClass("widget_fs20easylamp_off")) {
|
||||
widget.removeClass("widget_fs20easylamp_off");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
';
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20easylamp_getwidgethtml - HTML code for this widget
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20easylamp_get_widgethtml() {
|
||||
my $output = "";
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20easylamp_get_addwidget_setup_html - Create the selection of devices for this widget
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20easylamp_get_addwidget_setup_html() {
|
||||
my $output = "<script src='js/combobox.js'></script>
|
||||
<select name='fs20_combobox' id='combobox'>";
|
||||
my @list = (keys %defs);
|
||||
|
||||
foreach my $d (sort @list) {
|
||||
my $type = $defs{$d}{TYPE};
|
||||
my $name = $defs{$d}{NAME};
|
||||
|
||||
if( $type eq "FS20"){
|
||||
|
||||
$output = $output."<option value='$name'>$name</option>";
|
||||
}
|
||||
}
|
||||
|
||||
$output = $output."</select>";
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20easylamp_get_addwidget_prepare_attributes -
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20easylamp_get_addwidget_prepare_attributes() {
|
||||
my $output = '
|
||||
var temp_array = new Array();
|
||||
temp_array[0] = "attribute";
|
||||
temp_array[1] = $("#combobox option:selected").val()
|
||||
attributes_array[0] = temp_array;
|
||||
';
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20easylamp_getwidget_html - HTML code for this widget. DO WE NEED THIS ? SEE ABOVE
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20easylamp_getwidget_html() {
|
||||
my $output = " ";
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20easylamp_get_lamp_status - return the state of the lamp
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20easylamp_get_lamp_status () {
|
||||
my $attribute = YAF_getWidgetAttribute($_GET{"view_id"}, $_GET{"widget_id"}, "attribute");
|
||||
my $d = $defs{$attribute};
|
||||
return $d->{STATE};
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20easylamp_set_lamp_status - set the state of the lamp
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20easylamp_set_lamp_status() {
|
||||
my $attribute = YAF_getWidgetAttribute($_GET{"view_id"}, $_GET{"widget_id"}, "attribute");
|
||||
my $d = $defs{$attribute};
|
||||
Log 3, "set ".$d->{NAME}." ".$_GET{"status"};
|
||||
fhem "set ".$d->{NAME}." ".$_GET{"status"};
|
||||
}
|
||||
|
||||
1;
|
231
fhem/contrib/YAF/YAF/widgets/fs20st/fs20st.pm
Normal file
@ -0,0 +1,231 @@
|
||||
########################################################################################
|
||||
#
|
||||
# fs20st.pm - YAF widget for device FS20ST
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee, Prof. Dr. Peter A. Henning
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $yaf_version = 0.41;
|
||||
|
||||
use vars qw(%_GET);
|
||||
use vars qw(%defs);
|
||||
|
||||
#######################################################################################
|
||||
#
|
||||
# fs20st_get_widgetcss - Create the CSS code for this widget
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20st_get_widgetcss() {
|
||||
my $output = "
|
||||
.widget_fs20st {
|
||||
width: 33px;
|
||||
height: 33px;
|
||||
background-repeat:no-repeat;
|
||||
background-position:center center;
|
||||
opacity:1 !important;
|
||||
}
|
||||
|
||||
.widget_fs20st_on {
|
||||
background-image:url(./img/lamp_on.png) !important;
|
||||
}
|
||||
|
||||
.widget_fs20st_off {
|
||||
background-image:url(./img/lamp_off.png) !important;
|
||||
}
|
||||
";
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20st_get_widgetjs - Create the JavaScript code for this widget
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20st_get_widgetjs() {
|
||||
|
||||
my $output = '
|
||||
function fs20st_on_click(view_id, widget_id) {
|
||||
var widget = $("#widget_"+view_id+"_"+widget_id);
|
||||
var newState;
|
||||
if (widget.hasClass("widget_fs20st_on")) {
|
||||
newState = "off";
|
||||
} else{
|
||||
newState = "on";
|
||||
}
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/widget/fs20st/set_state",
|
||||
data: "view_id="+view_id+"&widget_id="+widget_id+"&state="+newState,
|
||||
context: document.body,
|
||||
success: function(){
|
||||
fs20st_update_widget(view_id, widget_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fs20st_update_widget(view_id, widget_id) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/widget/fs20st/get_state",
|
||||
data: "view_id="+view_id+"&widget_id="+widget_id,
|
||||
context: document.body,
|
||||
success: function(state) {
|
||||
var widget = $("#widget_"+view_id+"_"+widget_id);
|
||||
if (state == "off") {
|
||||
if (widget.hasClass("widget_fs20st_on")) {
|
||||
widget.removeClass("widget_fs20st_on");
|
||||
}
|
||||
if (!widget.hasClass("widget_fs20st_off")) {
|
||||
widget.addClass("widget_fs20st_off");
|
||||
}
|
||||
}
|
||||
else if (state == "on") {
|
||||
if (!widget.hasClass("widget_fs20st_on")) {
|
||||
widget.addClass("widget_fs20st_on");
|
||||
}
|
||||
if (widget.hasClass("widget_fs20st_off")) {
|
||||
widget.removeClass("widget_fs20st_off");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
';
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20st_getwidgethtml - HTML code for this widget
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20st_get_widgethtml() {
|
||||
my $output = "";
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20st_get_addwidget_setup_html - Create the selection of devices for this widget
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20st_get_addwidget_setup_html() {
|
||||
my $output = "<script src='js/combobox.js'></script>
|
||||
<select name='fs20_combobox' id='combobox'>";
|
||||
my @list = (keys %defs);
|
||||
|
||||
foreach my $d (sort @list) {
|
||||
my $type = $defs{$d}{TYPE};
|
||||
my $name = $defs{$d}{NAME};
|
||||
|
||||
if( $type eq "FS20" ){
|
||||
my $model = defined(AttrVal($name,"model",undef)) ? AttrVal($name,"model",undef) : "";
|
||||
if( $model eq "fs20st" ){
|
||||
#-- ignore those that are already defined in this view
|
||||
$output = $output."<option value='$name'>$name</option>"
|
||||
if( !YAF_isWidget($_GET{"view_id"},$name) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$output = $output."</select>";
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20st_get_addwidget_prepare_attributes -
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20st_get_addwidget_prepare_attributes() {
|
||||
my $output = '
|
||||
var temp_array = new Array();
|
||||
temp_array[0] = "fhemname";
|
||||
temp_array[1] = $("#combobox option:selected").val()
|
||||
attributes_array[0] = temp_array;
|
||||
';
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20st_getwidget_html - HTML code for this widget. DO WE NEED THIS ? SEE ABOVE
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20st_getwidget_html() {
|
||||
my $output = " ";
|
||||
return $output;
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20st_get_state - return the state of the switch
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20st_get_state () {
|
||||
my $name = YAF_getWidgetAttribute($_GET{"view_id"}, $_GET{"widget_id"}, "fhemname");
|
||||
my $d = $defs{$name};
|
||||
return $d->{STATE};
|
||||
}
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# fs20st_set_state - set the state of the switch
|
||||
#
|
||||
# no parameter
|
||||
#
|
||||
########################################################################################
|
||||
|
||||
sub fs20st_set_state() {
|
||||
my $name = YAF_getWidgetAttribute($_GET{"view_id"}, $_GET{"widget_id"}, "fhemname");
|
||||
Log 3, "set ".$name." ".$_GET{"state"};
|
||||
fhem "set ".$name." ".$_GET{"state"};
|
||||
}
|
||||
|
||||
1;
|
0
fhem/contrib/YAF/YAF/widgets/fs20st/www/.gitkeep
Normal file
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
Executable file
After Width: | Height: | Size: 180 B |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
Executable file
After Width: | Height: | Size: 178 B |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
Executable file
After Width: | Height: | Size: 120 B |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
Executable file
After Width: | Height: | Size: 105 B |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png
Executable file
After Width: | Height: | Size: 111 B |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
Executable file
After Width: | Height: | Size: 110 B |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
Executable file
After Width: | Height: | Size: 119 B |
After Width: | Height: | Size: 101 B |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-icons_222222_256x240.png
Executable file
After Width: | Height: | Size: 4.3 KiB |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-icons_2e83ff_256x240.png
Executable file
After Width: | Height: | Size: 4.3 KiB |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-icons_454545_256x240.png
Executable file
After Width: | Height: | Size: 4.3 KiB |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-icons_888888_256x240.png
Executable file
After Width: | Height: | Size: 4.3 KiB |
BIN
fhem/contrib/YAF/YAF/www/css/smoothness/images/ui-icons_cd0a0a_256x240.png
Executable file
After Width: | Height: | Size: 4.3 KiB |
461
fhem/contrib/YAF/YAF/www/css/smoothness/jquery-ui-1.9.1.custom.css
vendored
Executable file
@ -0,0 +1,461 @@
|
||||
/*! jQuery UI - v1.9.1 - 2012-10-25
|
||||
* http://jqueryui.com
|
||||
* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
|
||||
* To view and modify this theme, visit http://jqueryui.com/themeroller/
|
||||
* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
|
||||
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden { display: none; }
|
||||
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
|
||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
||||
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
|
||||
.ui-helper-clearfix:after { clear: both; }
|
||||
.ui-helper-clearfix { zoom: 1; }
|
||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
||||
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-disabled { cursor: default !important; }
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; }
|
||||
.ui-accordion .ui-accordion-icons { padding-left: 2.2em; }
|
||||
.ui-accordion .ui-accordion-noicons { padding-left: .7em; }
|
||||
.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; }
|
||||
.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
|
||||
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; }
|
||||
.ui-autocomplete {
|
||||
position: absolute;
|
||||
top: 0; /* #8656 */
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* workarounds */
|
||||
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
|
||||
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
|
||||
.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; }
|
||||
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
|
||||
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
|
||||
.ui-button-icons-only { width: 3.4em; }
|
||||
button.ui-button-icons-only { width: 3.7em; }
|
||||
|
||||
/*button text element */
|
||||
.ui-button .ui-button-text { display: block; line-height: 1.4; }
|
||||
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
|
||||
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
|
||||
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
|
||||
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
|
||||
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
|
||||
/* no icon support for input elements, provide padding by default */
|
||||
input.ui-button { padding: .4em 1em; }
|
||||
|
||||
/*button icon element(s) */
|
||||
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
|
||||
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
|
||||
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
|
||||
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
|
||||
/*button sets*/
|
||||
.ui-buttonset { margin-right: 7px; }
|
||||
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
|
||||
|
||||
/* workarounds */
|
||||
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
|
||||
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
|
||||
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
|
||||
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
|
||||
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
|
||||
.ui-datepicker .ui-datepicker-prev { left:2px; }
|
||||
.ui-datepicker .ui-datepicker-next { right:2px; }
|
||||
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
|
||||
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
|
||||
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
|
||||
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
|
||||
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
|
||||
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
|
||||
.ui-datepicker select.ui-datepicker-month,
|
||||
.ui-datepicker select.ui-datepicker-year { width: 49%;}
|
||||
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
|
||||
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
|
||||
.ui-datepicker td { border: 0; padding: 1px; }
|
||||
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
||||
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
|
||||
|
||||
/* with multiple calendars */
|
||||
.ui-datepicker.ui-datepicker-multi { width:auto; }
|
||||
.ui-datepicker-multi .ui-datepicker-group { float:left; }
|
||||
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
|
||||
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
|
||||
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
|
||||
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
|
||||
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
|
||||
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
|
||||
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
|
||||
.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
|
||||
|
||||
/* RTL support */
|
||||
.ui-datepicker-rtl { direction: rtl; }
|
||||
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||
|
||||
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
|
||||
.ui-datepicker-cover {
|
||||
position: absolute; /*must have*/
|
||||
z-index: -1; /*must have*/
|
||||
filter: mask(); /*must have*/
|
||||
top: -4px; /*must have*/
|
||||
left: -4px; /*must have*/
|
||||
width: 200px; /*must have*/
|
||||
height: 200px; /*must have*/
|
||||
}.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
|
||||
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
|
||||
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
|
||||
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
||||
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
||||
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
||||
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
||||
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
||||
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
||||
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
||||
.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; }
|
||||
.ui-menu .ui-menu { margin-top: -3px; position: absolute; }
|
||||
.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; }
|
||||
.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; }
|
||||
.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; }
|
||||
.ui-menu .ui-menu-item a.ui-state-focus,
|
||||
.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; }
|
||||
|
||||
.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; }
|
||||
.ui-menu .ui-state-disabled a { cursor: default; }
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons { position: relative; }
|
||||
.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; }
|
||||
|
||||
/* left-aligned */
|
||||
.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; }
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon { position: static; float: right; }
|
||||
.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
|
||||
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }.ui-resizable { position: relative;}
|
||||
.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; }
|
||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
|
||||
.ui-slider { position: relative; text-align: left; }
|
||||
.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
|
||||
.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
|
||||
|
||||
.ui-slider-horizontal { height: .8em; }
|
||||
.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
|
||||
.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
|
||||
.ui-slider-horizontal .ui-slider-range-min { left: 0; }
|
||||
.ui-slider-horizontal .ui-slider-range-max { right: 0; }
|
||||
|
||||
.ui-slider-vertical { width: .8em; height: 100px; }
|
||||
.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
|
||||
.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
|
||||
.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
|
||||
.ui-slider-vertical .ui-slider-range-max { top: 0; }.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; }
|
||||
.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; }
|
||||
.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; }
|
||||
.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */
|
||||
.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */
|
||||
.ui-spinner-up { top: 0; }
|
||||
.ui-spinner-down { bottom: 0; }
|
||||
|
||||
/* TR overrides */
|
||||
.ui-spinner .ui-icon-triangle-1-s {
|
||||
/* need to fix icons sprite */
|
||||
background-position:-65px -16px;
|
||||
}
|
||||
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
|
||||
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
|
||||
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; }
|
||||
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; }
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; }
|
||||
.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
|
||||
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
|
||||
.ui-tooltip {
|
||||
padding: 8px;
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
max-width: 300px;
|
||||
-webkit-box-shadow: 0 0 5px #aaa;
|
||||
box-shadow: 0 0 5px #aaa;
|
||||
}
|
||||
/* Fades and background-images don't work well together in IE6, drop the image */
|
||||
* html .ui-tooltip {
|
||||
background-image: none;
|
||||
}
|
||||
body .ui-tooltip { border-width: 2px; }
|
||||
|
||||
/* Component containers
|
||||
----------------------------------*/
|
||||
.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
|
||||
.ui-widget .ui-widget { font-size: 1em; }
|
||||
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
|
||||
.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
|
||||
.ui-widget-content a { color: #222222; }
|
||||
.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
|
||||
.ui-widget-header a { color: #222222; }
|
||||
|
||||
/* Interaction states
|
||||
----------------------------------*/
|
||||
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
|
||||
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
|
||||
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
|
||||
.ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited { color: #212121; text-decoration: none; }
|
||||
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
|
||||
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
|
||||
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
|
||||
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
|
||||
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
|
||||
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
|
||||
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
|
||||
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
||||
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
||||
.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
|
||||
.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
|
||||
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
|
||||
.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
|
||||
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
|
||||
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
|
||||
|
||||
/* positioning */
|
||||
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||
.ui-icon-extlink { background-position: -32px -80px; }
|
||||
.ui-icon-newwin { background-position: -48px -80px; }
|
||||
.ui-icon-refresh { background-position: -64px -80px; }
|
||||
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||
.ui-icon-document { background-position: -32px -96px; }
|
||||
.ui-icon-document-b { background-position: -48px -96px; }
|
||||
.ui-icon-note { background-position: -64px -96px; }
|
||||
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||
.ui-icon-comment { background-position: -128px -96px; }
|
||||
.ui-icon-person { background-position: -144px -96px; }
|
||||
.ui-icon-print { background-position: -160px -96px; }
|
||||
.ui-icon-trash { background-position: -176px -96px; }
|
||||
.ui-icon-locked { background-position: -192px -96px; }
|
||||
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||
.ui-icon-tag { background-position: -240px -96px; }
|
||||
.ui-icon-home { background-position: 0 -112px; }
|
||||
.ui-icon-flag { background-position: -16px -112px; }
|
||||
.ui-icon-calendar { background-position: -32px -112px; }
|
||||
.ui-icon-cart { background-position: -48px -112px; }
|
||||
.ui-icon-pencil { background-position: -64px -112px; }
|
||||
.ui-icon-clock { background-position: -80px -112px; }
|
||||
.ui-icon-disk { background-position: -96px -112px; }
|
||||
.ui-icon-calculator { background-position: -112px -112px; }
|
||||
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||
.ui-icon-search { background-position: -160px -112px; }
|
||||
.ui-icon-wrench { background-position: -176px -112px; }
|
||||
.ui-icon-gear { background-position: -192px -112px; }
|
||||
.ui-icon-heart { background-position: -208px -112px; }
|
||||
.ui-icon-star { background-position: -224px -112px; }
|
||||
.ui-icon-link { background-position: -240px -112px; }
|
||||
.ui-icon-cancel { background-position: 0 -128px; }
|
||||
.ui-icon-plus { background-position: -16px -128px; }
|
||||
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||
.ui-icon-minus { background-position: -48px -128px; }
|
||||
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||
.ui-icon-close { background-position: -80px -128px; }
|
||||
.ui-icon-closethick { background-position: -96px -128px; }
|
||||
.ui-icon-key { background-position: -112px -128px; }
|
||||
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||
.ui-icon-scissors { background-position: -144px -128px; }
|
||||
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||
.ui-icon-copy { background-position: -176px -128px; }
|
||||
.ui-icon-contact { background-position: -192px -128px; }
|
||||
.ui-icon-image { background-position: -208px -128px; }
|
||||
.ui-icon-video { background-position: -224px -128px; }
|
||||
.ui-icon-script { background-position: -240px -128px; }
|
||||
.ui-icon-alert { background-position: 0 -144px; }
|
||||
.ui-icon-info { background-position: -16px -144px; }
|
||||
.ui-icon-notice { background-position: -32px -144px; }
|
||||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-on { background-position: -96px -144px; }
|
||||
.ui-icon-radio-off { background-position: -112px -144px; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
.ui-icon-pause { background-position: -16px -160px; }
|
||||
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||
.ui-icon-stop { background-position: -96px -160px; }
|
||||
.ui-icon-eject { background-position: -112px -160px; }
|
||||
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||
.ui-icon-power { background-position: 0 -176px; }
|
||||
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||
.ui-icon-signal { background-position: -32px -176px; }
|
||||
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Corner radius */
|
||||
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
|
||||
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); }
|
||||
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }
|
5
fhem/contrib/YAF/YAF/www/css/smoothness/jquery-ui-1.9.1.custom.min.css
vendored
Executable file
100
fhem/contrib/YAF/YAF/www/css/yaf.css
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* ########################################################################################
|
||||
*
|
||||
* yaf.css
|
||||
*
|
||||
* YAF - Yet Another Floorplan
|
||||
* FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
* Markus Mangei, Daniel Weisensee
|
||||
*
|
||||
* ########################################################################################
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* ########################################################################################
|
||||
*/
|
||||
#menue {
|
||||
width: 250px;
|
||||
float: left;
|
||||
height: 550px;
|
||||
}
|
||||
|
||||
#content {
|
||||
float: left;
|
||||
height: 550px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
height: 500px;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.menue_button {
|
||||
width: 240px
|
||||
}
|
||||
|
||||
.menue_block {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#menue_button_editview {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#dialog_manageviews-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#dialog_manageviews-table col.col1 { }
|
||||
#dialog_manageviews-table col.col2 { width:20px; }
|
||||
#dialog_manageviews-table col.col3 { width:20px; }
|
||||
|
||||
.loading_animation {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: rgba( 255, 255, 255, .8 )
|
||||
url('../img/loading.gif')
|
||||
50% 50%
|
||||
no-repeat;
|
||||
}
|
||||
|
||||
.widgets {
|
||||
padding: 0em;
|
||||
position: absolute;
|
||||
width: 33px;
|
||||
height: 33px;
|
||||
cursor: move;
|
||||
opacity: 1;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#widget_menue {
|
||||
padding: 0em;
|
||||
position: absolute;
|
||||
width: 100px;
|
||||
height: 33px;
|
||||
border: 1px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.widget_menue {
|
||||
width: 33px;
|
||||
height: 33px;
|
||||
float: left;
|
||||
}
|
BIN
fhem/contrib/YAF/YAF/www/img/1og.jpeg
Executable file
After Width: | Height: | Size: 62 KiB |
BIN
fhem/contrib/YAF/YAF/www/img/eg.jpeg
Executable file
After Width: | Height: | Size: 72 KiB |
BIN
fhem/contrib/YAF/YAF/www/img/lamp_off.png
Executable file
After Width: | Height: | Size: 766 B |
BIN
fhem/contrib/YAF/YAF/www/img/lamp_on.png
Executable file
After Width: | Height: | Size: 831 B |
BIN
fhem/contrib/YAF/YAF/www/img/loading.gif
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
fhem/contrib/YAF/YAF/www/img/wetter.png
Normal file
After Width: | Height: | Size: 19 KiB |
128
fhem/contrib/YAF/YAF/www/js/combobox.js
Normal file
@ -0,0 +1,128 @@
|
||||
(function( $ ) {
|
||||
$.widget( "ui.combobox", {
|
||||
_create: function() {
|
||||
var input,
|
||||
that = this,
|
||||
wasOpen = false,
|
||||
select = this.element.hide(),
|
||||
selected = select.children( ":selected" ),
|
||||
value = selected.val() ? selected.text() : "",
|
||||
wrapper = this.wrapper = $( "<span>" )
|
||||
.addClass( "ui-combobox" )
|
||||
.insertAfter( select );
|
||||
|
||||
function removeIfInvalid( element ) {
|
||||
var value = $( element ).val(),
|
||||
matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( value ) + "$", "i" ),
|
||||
valid = false;
|
||||
select.children( "option" ).each(function() {
|
||||
if ( $( this ).text().match( matcher ) ) {
|
||||
this.selected = valid = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if ( !valid ) {
|
||||
// remove invalid value, as it didn't match anything
|
||||
$( element )
|
||||
.val( "" )
|
||||
.attr( "title", value + " didn't match any item" )
|
||||
.tooltip( "open" );
|
||||
select.val( "" );
|
||||
setTimeout(function() {
|
||||
input.tooltip( "close" ).attr( "title", "" );
|
||||
}, 2500 );
|
||||
input.data( "ui-autocomplete" ).term = "";
|
||||
}
|
||||
}
|
||||
|
||||
input = $( "<input>" )
|
||||
.appendTo( wrapper )
|
||||
.val( value )
|
||||
.attr( "title", "" )
|
||||
.addClass( "ui-state-default ui-combobox-input" )
|
||||
.autocomplete({
|
||||
delay: 0,
|
||||
minLength: 0,
|
||||
source: function( request, response ) {
|
||||
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
|
||||
response( select.children( "option" ).map(function() {
|
||||
var text = $( this ).text();
|
||||
if ( this.value && ( !request.term || matcher.test(text) ) )
|
||||
return {
|
||||
label: text.replace(
|
||||
new RegExp(
|
||||
"(?![^&;]+;)(?!<[^<>]*)(" +
|
||||
$.ui.autocomplete.escapeRegex(request.term) +
|
||||
")(?![^<>]*>)(?![^&;]+;)", "gi"
|
||||
), "<strong>$1</strong>" ),
|
||||
value: text,
|
||||
option: this
|
||||
};
|
||||
}) );
|
||||
},
|
||||
select: function( event, ui ) {
|
||||
ui.item.option.selected = true;
|
||||
that._trigger( "selected", event, {
|
||||
item: ui.item.option
|
||||
});
|
||||
},
|
||||
change: function( event, ui ) {
|
||||
if ( !ui.item ) {
|
||||
removeIfInvalid( this );
|
||||
}
|
||||
}
|
||||
})
|
||||
.addClass( "ui-widget ui-widget-content ui-corner-left" );
|
||||
|
||||
input.data( "ui-autocomplete" )._renderItem = function( ul, item ) {
|
||||
return $( "<li>" )
|
||||
.append( "<a>" + item.label + "</a>" )
|
||||
.appendTo( ul );
|
||||
};
|
||||
|
||||
$( "<a>" )
|
||||
.attr( "tabIndex", -1 )
|
||||
.tooltip()
|
||||
.appendTo( wrapper )
|
||||
.button({
|
||||
icons: {
|
||||
primary: "ui-icon-triangle-1-s"
|
||||
},
|
||||
text: false
|
||||
})
|
||||
.removeClass( "ui-corner-all" )
|
||||
.addClass( "ui-corner-right ui-combobox-toggle" )
|
||||
.mousedown(function() {
|
||||
wasOpen = input.autocomplete( "widget" ).is( ":visible" );
|
||||
})
|
||||
.click(function() {
|
||||
input.focus();
|
||||
|
||||
// close if already visible
|
||||
if ( wasOpen ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// pass empty string as value to search for, displaying all results
|
||||
input.autocomplete( "search", "" );
|
||||
});
|
||||
|
||||
input.tooltip({
|
||||
tooltipClass: "ui-state-highlight"
|
||||
});
|
||||
},
|
||||
|
||||
_destroy: function() {
|
||||
this.wrapper.remove();
|
||||
this.element.show();
|
||||
}
|
||||
});
|
||||
})( jQuery );
|
||||
|
||||
$(function() {
|
||||
$( "#combobox" ).combobox();
|
||||
$( "#toggle" ).click(function() {
|
||||
$( "#combobox" ).toggle();
|
||||
});
|
||||
});
|
9440
fhem/contrib/YAF/YAF/www/js/jquery-1.8.2.js
vendored
Executable file
14823
fhem/contrib/YAF/YAF/www/js/jquery-ui-1.9.1.custom.js
vendored
Executable file
6
fhem/contrib/YAF/YAF/www/js/jquery-ui-1.9.1.custom.min.js
vendored
Executable file
160
fhem/contrib/YAF/YAF/www/js/jquery.ui.touch-punch.min.js
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
/*!
|
||||
* jQuery UI Touch Punch 0.2.2
|
||||
*
|
||||
* Copyright 2011, Dave Furfero
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.mouse.js
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
// Detect touch support
|
||||
$.support.touch = 'ontouchend' in document;
|
||||
|
||||
// Ignore browsers without touch support
|
||||
if (!$.support.touch) {
|
||||
return;
|
||||
}
|
||||
|
||||
var mouseProto = $.ui.mouse.prototype,
|
||||
_mouseInit = mouseProto._mouseInit,
|
||||
touchHandled;
|
||||
|
||||
/**
|
||||
* Simulate a mouse event based on a corresponding touch event
|
||||
* @param {Object} event A touch event
|
||||
* @param {String} simulatedType The corresponding mouse event
|
||||
*/
|
||||
function simulateMouseEvent (event, simulatedType) {
|
||||
|
||||
// Ignore multi-touch events
|
||||
if (event.originalEvent.touches.length > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var touch = event.originalEvent.changedTouches[0],
|
||||
simulatedEvent = document.createEvent('MouseEvents');
|
||||
|
||||
// Initialize the simulated mouse event using the touch event's coordinates
|
||||
simulatedEvent.initMouseEvent(
|
||||
simulatedType, // type
|
||||
true, // bubbles
|
||||
true, // cancelable
|
||||
window, // view
|
||||
1, // detail
|
||||
touch.screenX, // screenX
|
||||
touch.screenY, // screenY
|
||||
touch.clientX, // clientX
|
||||
touch.clientY, // clientY
|
||||
false, // ctrlKey
|
||||
false, // altKey
|
||||
false, // shiftKey
|
||||
false, // metaKey
|
||||
0, // button
|
||||
null // relatedTarget
|
||||
);
|
||||
|
||||
// Dispatch the simulated event to the target element
|
||||
event.target.dispatchEvent(simulatedEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the jQuery UI widget's touchstart events
|
||||
* @param {Object} event The widget element's touchstart event
|
||||
*/
|
||||
mouseProto._touchStart = function (event) {
|
||||
|
||||
var self = this;
|
||||
|
||||
// Ignore the event if another widget is already being handled
|
||||
if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the flag to prevent other widgets from inheriting the touch event
|
||||
touchHandled = true;
|
||||
|
||||
// Track movement to determine if interaction was a click
|
||||
self._touchMoved = false;
|
||||
|
||||
// Simulate the mouseover event
|
||||
simulateMouseEvent(event, 'mouseover');
|
||||
|
||||
// Simulate the mousemove event
|
||||
simulateMouseEvent(event, 'mousemove');
|
||||
|
||||
// Simulate the mousedown event
|
||||
simulateMouseEvent(event, 'mousedown');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the jQuery UI widget's touchmove events
|
||||
* @param {Object} event The document's touchmove event
|
||||
*/
|
||||
mouseProto._touchMove = function (event) {
|
||||
|
||||
// Ignore event if not handled
|
||||
if (!touchHandled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Interaction was not a click
|
||||
this._touchMoved = true;
|
||||
|
||||
// Simulate the mousemove event
|
||||
simulateMouseEvent(event, 'mousemove');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the jQuery UI widget's touchend events
|
||||
* @param {Object} event The document's touchend event
|
||||
*/
|
||||
mouseProto._touchEnd = function (event) {
|
||||
|
||||
// Ignore event if not handled
|
||||
if (!touchHandled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Simulate the mouseup event
|
||||
simulateMouseEvent(event, 'mouseup');
|
||||
|
||||
// Simulate the mouseout event
|
||||
simulateMouseEvent(event, 'mouseout');
|
||||
|
||||
// If the touch interaction did not move, it should trigger a click
|
||||
if (!this._touchMoved) {
|
||||
|
||||
// Simulate the click event
|
||||
simulateMouseEvent(event, 'click');
|
||||
}
|
||||
|
||||
// Unset the flag to allow other widgets to inherit the touch event
|
||||
touchHandled = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* A duck punch of the $.ui.mouse _mouseInit method to support touch events.
|
||||
* This method extends the widget with bound touch event handlers that
|
||||
* translate touch events to mouse events and pass them to the widget's
|
||||
* original mouse event handling methods.
|
||||
*/
|
||||
mouseProto._mouseInit = function () {
|
||||
|
||||
var self = this;
|
||||
|
||||
// Delegate the touch handlers to the widget's element
|
||||
self.element
|
||||
.bind('touchstart', $.proxy(self, '_touchStart'))
|
||||
.bind('touchmove', $.proxy(self, '_touchMove'))
|
||||
.bind('touchend', $.proxy(self, '_touchEnd'));
|
||||
|
||||
// Call the original $.ui.mouse init method
|
||||
_mouseInit.call(self);
|
||||
};
|
||||
|
||||
})(jQuery);
|
438
fhem/contrib/YAF/YAF/www/js/yaf-basics.js
Normal file
@ -0,0 +1,438 @@
|
||||
/*
|
||||
* ########################################################################################
|
||||
*
|
||||
* yaf-basics.js
|
||||
*
|
||||
* YAF - Yet Another Floorplan
|
||||
* FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
* Markus Mangei, Daniel Weisensee, Prof. Dr. Peter A. Henning
|
||||
*
|
||||
* ########################################################################################
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* ########################################################################################
|
||||
*/
|
||||
function get_current_view_id() {
|
||||
return current_view_id;
|
||||
}
|
||||
|
||||
function get_current_widget_id() {
|
||||
return current_widget_id;
|
||||
}
|
||||
|
||||
// Ändert den Modus der Oberfläche
|
||||
// mode: id des Modus
|
||||
function switch_mode(new_mode) {
|
||||
view_mode = new_mode;
|
||||
if (new_mode == 0) {
|
||||
// Live Modus
|
||||
$(".widgets").draggable("disable");
|
||||
} else if (new_mode == 1) {
|
||||
// Positionierungsmodus
|
||||
$(".widgets").draggable("enable");
|
||||
}
|
||||
}
|
||||
|
||||
// Timer für den Reload
|
||||
// Wenn startIntervall = 1 ist, dann wird die Schleife gestartet,
|
||||
// ansonsten ist es ein einmaliger aufruf
|
||||
function refreshWidgets() {
|
||||
$.each(widgets, function (index, widget) {
|
||||
update_widget(widget[0], widget[1], widget[2])
|
||||
});
|
||||
setTimeout(function () {
|
||||
refreshWidgets();
|
||||
},
|
||||
refreshTime * 1000);
|
||||
}
|
||||
|
||||
function init_RefreshWidgets() {
|
||||
$.ajax({
|
||||
async: true,
|
||||
url: "../../ajax/global/getRefreshTime",
|
||||
context: document.body,
|
||||
success: function (_refreshTime) {
|
||||
refreshTime = _refreshTime;
|
||||
refreshWidgets();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Läd die Sichten über AJAX vom Server.
|
||||
// callback: wird aufgerufen, wenn der Server geantwortet hat
|
||||
function load_views(callback) {
|
||||
console.log("called load_views()");
|
||||
$.ajax({
|
||||
async: true,
|
||||
url: "../../ajax/global/getViews",
|
||||
context: document.body,
|
||||
success: function (jsondata) {
|
||||
views = jQuery.parseJSON(jsondata);
|
||||
console.log(views);
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Fügt eine neue Sicht zu den Tabs hinzu.
|
||||
// id: Id der Sicht
|
||||
// name: Name der Sicht
|
||||
function add_tab(id, name) {
|
||||
console.log("called add_tab()");
|
||||
// Neues Div nur erzeugen, wenn es noch keins mit der entsprechenden Id gibt
|
||||
if ($("#tabs-" + id).length <= 0) {
|
||||
$("#tabs").append("<div id=\"tabs-" + id + "\" class=\"loaded tab\"></div>");
|
||||
}
|
||||
$("#views").append("<li id=\"tabs_li-" + id + "\"><a href=\"#tabs-" + id + "\">" + name + "</a></li>");
|
||||
$("#tabs").tabs("refresh");
|
||||
return;
|
||||
}
|
||||
|
||||
// Löscht eine Sicht aus den Tabs.
|
||||
// Das <div> sowie der <li> Eintrag werden gelöscht.
|
||||
// id: Id der zu löschenden Sicht
|
||||
function delete_tab(id) {
|
||||
// Kann noch optimiert werden!
|
||||
console.log("called delete_tab()");
|
||||
$("#tabs-" + id).remove();
|
||||
$("#tabs_li-" + id).remove();
|
||||
load_views(show_views);
|
||||
return;
|
||||
}
|
||||
|
||||
// Zeigt alle Tabs neu an.
|
||||
// Zuerst werden alle Tabs gelöscht und anschließend neu anzeigen.
|
||||
function show_views() {
|
||||
console.log("called show_views()");
|
||||
$("#views").html("");
|
||||
|
||||
if (views.length == 0) {
|
||||
$('#views').hide();
|
||||
$('#tabs_error').html("Es wurden keine Sichten gefunden!");
|
||||
$('#tabs_error').show();
|
||||
} else {
|
||||
$('#tabs_error').hide();
|
||||
$('#views').show();
|
||||
var selected_view_id = get_current_view_id();
|
||||
var selected = 0;
|
||||
var minId = 999;
|
||||
$.each(views, function (index, view) {
|
||||
add_tab(view[0], view[1]);
|
||||
if (selected_view_id == view[0]) {
|
||||
$('#tabs').tabs("select", "#tabs-" + view[0]);
|
||||
selected = 1;
|
||||
}
|
||||
if (view[0] < minId) {
|
||||
minId = view[0];
|
||||
}
|
||||
});
|
||||
if (! selected) {
|
||||
$('#tabs').tabs("select", "#tabs-" + minId);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Zeigt ein neues Hintergrundbild in einer bestimmten Sicht an.
|
||||
// view_id: Die Sicht, in der das Hintergrundbild eingefügt werden soll
|
||||
// file: Pfad und Dateiname der Grafik
|
||||
// x_pos: x Positon
|
||||
// y_pos: y Position
|
||||
function add_background_image(view_id, file, x_pos, y_pos) {
|
||||
$("#tabs-" + view_id).append("<img src=\"" + file + "\" />");
|
||||
}
|
||||
|
||||
function update_widget(name, view_id, widget_id) {
|
||||
console.log("update_widget " + name);
|
||||
try {
|
||||
eval(name + "_update_widget(" + view_id + ", " + widget_id + ")");
|
||||
}
|
||||
catch (exception) {
|
||||
console.log("Error in update_widget()");
|
||||
}
|
||||
}
|
||||
|
||||
// Zeigt ein neues Widget in einer bestimmten Sicht an.
|
||||
// view_id: Die Sicht, in der das Hintergrundbild eingefügt werden soll
|
||||
// name: Typ des Widgets
|
||||
// x_pos: x Positon
|
||||
// y_pos: y Position
|
||||
// attr_array: Ein Array mit den Attributen des Widgets.
|
||||
function add_widget(view_id, widget_id, name, x_pos, y_pos, attr_array) {
|
||||
var widget_html = "";
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: false,
|
||||
url: "../../ajax/widget/" + name + "/getwidget_html",
|
||||
context: document.body,
|
||||
success: function (result) {
|
||||
widget_html = result;
|
||||
}
|
||||
});
|
||||
$("#tabs-" + view_id).append("<div id=\"widget_" + view_id + "_" + widget_id + "\" class=\"widgets widget_" + name + "\" style=\"left: " + x_pos + "px; top: " + y_pos + "px;\">" + widget_html + "</div>");
|
||||
|
||||
update_widget(name, view_id, widget_id);
|
||||
|
||||
$("#widget_" + view_id + "_" + widget_id).click(function () {
|
||||
if (view_mode == 0) {
|
||||
try {
|
||||
eval(name + "_on_click(" + view_id + ", " + widget_id + ")");
|
||||
}
|
||||
catch (exception) {
|
||||
console.log("Error in on_click()");
|
||||
}
|
||||
} else if (view_mode == 1) {
|
||||
if (! widgetWasMoved) {
|
||||
$("#widget_menue").show();
|
||||
current_widget_id = widget_id;
|
||||
var top = $("#widget_" + view_id + "_" + widget_id).position().top;
|
||||
var left = $("#widget_" + view_id + "_" + widget_id).position().left;
|
||||
// Nach links anzeigen
|
||||
var offsetLeft = $("#widget_" + view_id + "_" + widget_id).width();
|
||||
var positionLeft = left + offsetLeft - 10;
|
||||
var positionTop = top - 23;
|
||||
$("#widget_menue").css("top", positionTop);
|
||||
$("#widget_menue").css("left", positionLeft);
|
||||
setTimeout(function () {
|
||||
if (close_widget_menue) {
|
||||
$("#widget_menue").hide();
|
||||
}
|
||||
},
|
||||
2500);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#widget_" + view_id + "_" + widget_id).draggable({
|
||||
containment: "parent",
|
||||
start: function (event, ui) {
|
||||
close_widget_menue = true;
|
||||
$("#widget_menue").hide();
|
||||
},
|
||||
stop: function (event, ui) {
|
||||
widgetWasMoved = true;
|
||||
setTimeout(function () {
|
||||
widgetWasMoved = false;
|
||||
},
|
||||
500);
|
||||
// Neue Position des Widget speichern. Kommastellen werden abgeschnitten.
|
||||
x_pos = parseInt(ui.position.left);
|
||||
y_pos = parseInt(ui.position.top);
|
||||
widget_id = $(event.target).attr("id").split("_")[2];
|
||||
view_id = $(event.target).attr("id").split("_")[1];
|
||||
console.log("view-id: " + get_current_view_id() + " widget-id: " + widget_id + " x-pos: " + x_pos + " y-pos: " + y_pos);
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/global/setWidgetPosition",
|
||||
data: "view_id=" + view_id + "&widget_id=" + widget_id + "&x_pos=" + x_pos + "&y_pos=" + y_pos,
|
||||
context: document.body,
|
||||
success: function (jsondata) {
|
||||
console.log("Widget Position geändert: " + jsondata)
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// widget in Widgetliste einfügen
|
||||
var widget = new Array(name, get_current_view_id(), widget_id);
|
||||
widgets[widgets.length] = widget;
|
||||
}
|
||||
|
||||
// Behandelt das öffnen eines Tabs
|
||||
// Entweder der Inhalt wurde bereits geladen, oder er muss über
|
||||
// Ajax nachgeladen werden.
|
||||
function activate_tab(view_id) {
|
||||
if (! $("#tabs-" + view_id).hasClass("isLoaded")) {
|
||||
current_view_id = view_id;
|
||||
console.log("activate tab: " + view_id);
|
||||
console.log("load widgets");
|
||||
$("#tabs-" + view_id).html("");
|
||||
// Speichern, dass view bereits geladen wurde
|
||||
$("#tabs-" + view_id).addClass("isLoaded");
|
||||
$("#tabs-" + view_id).html("");
|
||||
$.ajax({
|
||||
async: false,
|
||||
url: "../../ajax/global/getView",
|
||||
data: "id=" + view_id,
|
||||
context: document.body,
|
||||
success: function (jsondata) {
|
||||
var view_data = jQuery.parseJSON(jsondata);
|
||||
// background images laden
|
||||
if (view_data.backgrounds) {
|
||||
$.each(view_data.backgrounds, function (index, background) {
|
||||
add_background_image(view_id, background.img_url, background.x_pos, background.y_pos);
|
||||
});
|
||||
} else {
|
||||
console.log("keine Hintergrundbilder vorhanden!");
|
||||
}
|
||||
// widgets laden
|
||||
if (view_data.widgets) {
|
||||
$.each(view_data.widgets, function (index, widget) {
|
||||
widget_x_pos = widget.x_pos;
|
||||
widget_y_pos = widget.y_pos;
|
||||
widget_name = widget.name;
|
||||
widget_id = widget.id;
|
||||
add_widget(view_id, widget_id, widget_name, widget_x_pos, widget_y_pos, 0);
|
||||
});
|
||||
// Aktueller View Mode für alle Widgets aktualisiert
|
||||
switch_mode(view_mode);
|
||||
} else {
|
||||
console.log("keine widgets vorhanden!");
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
current_view_id = view_id;
|
||||
console.log("switch to activated tab: " + view_id);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialisiert die Tabs. Diese Funktion muss nur einmal aufgerufen werden.
|
||||
// Sobald das Tab gewechselt wird, wird die Funktion activate_tab(id)
|
||||
// aufgerufen.
|
||||
function init_tabs() {
|
||||
$("#tabs").tabs({
|
||||
activate: function (event, ui) {
|
||||
activate_tab(ui.newPanel.selector.substr(6));
|
||||
},
|
||||
create: function (event, ui) {
|
||||
//activate_tab(ui.panel.selector.substr(6));
|
||||
}
|
||||
});
|
||||
$("#tabs").resizable({
|
||||
containment: $(".widgets")
|
||||
});
|
||||
}
|
||||
|
||||
// Initialisiert das Menü.
|
||||
function init_menue() {
|
||||
$("#button_back").button({
|
||||
icons: {
|
||||
secondary: "ui-icon-circle-arrow-w"
|
||||
}
|
||||
});
|
||||
|
||||
$("#button_addview").button({
|
||||
icons: {
|
||||
secondary: "ui-icon-plusthick"
|
||||
}
|
||||
});
|
||||
|
||||
$("#button_manageviews").button({
|
||||
icons: {
|
||||
secondary: "ui-icon-plusthick"
|
||||
}
|
||||
});
|
||||
|
||||
$("#button_addwidget").button({
|
||||
icons: {
|
||||
secondary: "ui-icon-plusthick"
|
||||
}
|
||||
});
|
||||
|
||||
$("#button_managewidgets").button({
|
||||
icons: {
|
||||
secondary: "ui-icon-plusthick"
|
||||
}
|
||||
});
|
||||
|
||||
$("#button_settings").button({
|
||||
icons: {
|
||||
secondary: "ui-icon-pencil"
|
||||
}
|
||||
});
|
||||
|
||||
$("#widget_menue_edit").button({
|
||||
icons: {
|
||||
secondary: "ui-icon-pencil"
|
||||
}
|
||||
});
|
||||
|
||||
$("#widget_menue_delete").button({
|
||||
icons: {
|
||||
secondary: "ui-icon-trash"
|
||||
}
|
||||
});
|
||||
|
||||
$("#button_editview").buttonset();
|
||||
}
|
||||
|
||||
// Initialisiert die Handler
|
||||
function init_handlers() {
|
||||
$("#button_back").click(function () {
|
||||
window.location.href = "../../../../fhem";
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#button_settings").click(function () {
|
||||
$("#dialog_settings").dialog("open");
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#button_addview").click(function () {
|
||||
$("#dialog_addview").dialog("open");
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#button_manageviews").click(function () {
|
||||
$("#dialog_manageviews").dialog("open");
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#button_addwidget").click(function () {
|
||||
$("#dialog_addwidget").dialog("open");
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#button_switchmode_0").click(function () {
|
||||
if (view_mode != 0) {
|
||||
switch_mode(0);
|
||||
}
|
||||
});
|
||||
|
||||
$("#button_switchmode_1").click(function () {
|
||||
if (view_mode != 1) {
|
||||
switch_mode(1);
|
||||
}
|
||||
});
|
||||
|
||||
$("#widget_menue_delete").click(function () {
|
||||
$("#label_deletewidget").html("xy");
|
||||
$("#dialog_deletewidget").dialog("open");
|
||||
});
|
||||
|
||||
$("#widget_menue_edit").click(function () {
|
||||
$("#label_editwidget").html("xy");
|
||||
$("#dialog_editwidget").dialog("open");
|
||||
$("#widget_menue").hide();
|
||||
close_widget_menue = true;
|
||||
});
|
||||
|
||||
$("#widget_menue").mouseenter(function () {
|
||||
close_widget_menue = false;
|
||||
});
|
||||
|
||||
$("#widget_menue").mouseleave(function () {
|
||||
close_widget_menue = true;
|
||||
$("#widget_menue").hide();
|
||||
});
|
||||
}
|
371
fhem/contrib/YAF/YAF/www/js/yaf-dialogs.js
Normal file
@ -0,0 +1,371 @@
|
||||
/*
|
||||
* ########################################################################################
|
||||
*
|
||||
* yaf-dialogs.js
|
||||
*
|
||||
* YAF - Yet Another Floorplan
|
||||
* FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
* Markus Mangei, Daniel Weisensee, Prof. Dr. Peter A. Henning
|
||||
*
|
||||
* ########################################################################################
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* ########################################################################################
|
||||
*/
|
||||
// Initialisiert die Dialoge
|
||||
function init_dialogs() {
|
||||
$("#dialog_addview").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 300,
|
||||
width: 400,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Hinzufügen": function (event) {
|
||||
console.log("before: " + views);
|
||||
$("#dialog_addview_loading").show();
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/global/addView",
|
||||
data: "name=" + $("#dialog_addview_name").val(),
|
||||
context: document.body,
|
||||
success: function (jsondata) {
|
||||
$("#dialog_addview").dialog("close");
|
||||
load_views(show_views);
|
||||
$("#dialog_addview_loading").hide();
|
||||
console.log("after: " + views);
|
||||
}
|
||||
});
|
||||
$(this).dialog("close");
|
||||
},
|
||||
"Abbrechen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#dialog_deleteview").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 300,
|
||||
width: 400,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Löschen": function (ui) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: false,
|
||||
url: "../../ajax/global/deleteView",
|
||||
data: "id=" + delete_view_id,
|
||||
context: document.body,
|
||||
success: function (jsondata) {
|
||||
delete_tab(delete_view_id);
|
||||
$("#dialog_deleteview").dialog("close");
|
||||
$("#manageviews_tr_" + delete_view_id).remove();
|
||||
}
|
||||
});
|
||||
$(this).dialog("close");
|
||||
},
|
||||
"Abbrechen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#dialog_editview").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 300,
|
||||
width: 400,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Speichern": function (ui) {
|
||||
console.log("before: " + views);
|
||||
$("#dialog_editview_loading").show();
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/global/editView",
|
||||
data: "id=" + edit_view_id + "&name=" + $("#dialog_editview_name").val(),
|
||||
context: document.body,
|
||||
success: function (jsondata) {
|
||||
load_views(show_views);
|
||||
$($("#manageviews_tr_" + edit_view_id).children().get(0)).text($("#dialog_editview_name").val());
|
||||
$("#dialog_editview_loading").hide();
|
||||
$("#dialog_editview").dialog("close");
|
||||
}
|
||||
});
|
||||
$(this).dialog("close");
|
||||
},
|
||||
"Abbrechen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("#dialog_addwidget").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 500,
|
||||
width: 600,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Schließen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
},
|
||||
open: function (event, ui) {
|
||||
$("#dialog_addwidget_loading").show();
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/global/getWidgets",
|
||||
context: document.body,
|
||||
success: function (jsondata) {
|
||||
var widgets = jQuery.parseJSON(jsondata);
|
||||
$("#dialog_addwidget_table").html("<colgroup><col class=\"col1\"><col class=\"col2\"><col class=\"col3\"></colgroup>");
|
||||
if (widgets) {
|
||||
$.each(widgets, function (index, widget) {
|
||||
$("#dialog_addwidget_table").append("<tr><td>" + widget + "</td><td></td><td><button class=\"button_addwidget\" id=\"addwidget_" + widget + "\"> </button></td></tr>");
|
||||
});
|
||||
$(".button_addwidget").button({
|
||||
icons: {
|
||||
primary: "ui-icon-circle-plus"
|
||||
},
|
||||
text: false
|
||||
});
|
||||
$(".button_addwidget").click(function (ui) {
|
||||
add_widget_name = $(ui.currentTarget).attr("id").substr(10);
|
||||
$("#dialog_addwidget_setup_widget").html(add_widget_name);
|
||||
$("#dialog_addwidget_setup").dialog("open");
|
||||
$("#dialog_addwidget_setup_loading").show();
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/widget/" + add_widget_name + "/get_addwidget_setup_html",
|
||||
context: document.body,
|
||||
success: function (html_result) {
|
||||
if (html_result != 0) {
|
||||
$("#dialog_addwidget_setup_form").html(html_result);
|
||||
} else {
|
||||
$("#dialog_addwidget_setup_form").html("Das Widget stellt keine Konfigurationsmöglichkeiten bereit!")
|
||||
}
|
||||
$("#dialog_addwidget_setup_loading").hide();
|
||||
}
|
||||
});
|
||||
console.log("widget hinzufügen: " + add_widget_name)
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
console.log("keine Widgets vorhanden!")
|
||||
}
|
||||
$("#dialog_addwidget_loading").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$("#dialog_addwidget_setup").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 350,
|
||||
width: 400,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Hinzufügen": function (event) {
|
||||
$("#dialog_addwidget_setup_loading").show();
|
||||
var attributes_array = new Array();
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: false,
|
||||
url: "../../ajax/widget/" + add_widget_name + "/get_addwidget_prepare_attributes",
|
||||
context: document.body,
|
||||
success: function (js_result) {
|
||||
try {
|
||||
eval(js_result);
|
||||
}
|
||||
catch (exception) {
|
||||
console.log("exception in dialog_addwidget_setup dialog event");
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(JSON.stringify(attributes_array));
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: false,
|
||||
url: "../../ajax/global/addWidget",
|
||||
data: "view_id=" + current_view_id + "&widget=" + add_widget_name + "&attributes=" + JSON.stringify(attributes_array),
|
||||
context: document.body,
|
||||
success: function (widgetId) {
|
||||
// Position links oben x= 28 y = 69, muss auch in 01_YAF.pm in addWidget() Methode angepasst werden!
|
||||
add_widget(current_view_id, widgetId, add_widget_name, 28, 69, attributes_array);
|
||||
// Aktueller View Mode für alle Widgets aktualisiert
|
||||
switch_mode(view_mode);
|
||||
}
|
||||
});
|
||||
$("#dialog_addwidget_setup_loading").hide();
|
||||
|
||||
$(this).dialog("close");
|
||||
},
|
||||
"Abbrechen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
},
|
||||
open: function (event, ui) {
|
||||
console.log("dialog widget hinzufügen geöffnet => inhalt laden");
|
||||
}
|
||||
});
|
||||
|
||||
$("#dialog_deletewidget").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 300,
|
||||
width: 400,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Löschen": function (ui) {
|
||||
var view_id = get_current_view_id();
|
||||
var widget_id = get_current_widget_id();
|
||||
console.log("delete view " + view_id + " widget " + widget_id);
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: false,
|
||||
url: "../../ajax/global/deleteWidget",
|
||||
data: "view_id=" + view_id + "&widget_id" + widget_id,
|
||||
context: document.body,
|
||||
success: function (jsondata) {
|
||||
console.log("widget deleted");
|
||||
$("#dialog_deletewidget").dialog("close");
|
||||
$("#widget_menue").hide();
|
||||
$("#widget_" + view_id + "_" + widget_id).remove();
|
||||
}
|
||||
});
|
||||
$(this).dialog("close");
|
||||
},
|
||||
"Abbrechen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#dialog_editwidget").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 300,
|
||||
width: 400,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Speichern": function (ui) {
|
||||
$(this).dialog("close");
|
||||
},
|
||||
"Abbrechen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("#dialog_manageviews").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 500,
|
||||
width: 600,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Schließen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
},
|
||||
open: function (event, ui) {
|
||||
$("#dialog_manageviews-table").html("<colgroup><col class=\"col1\"><col class=\"col2\"><col class=\"col3\"></colgroup>");
|
||||
$.each(views, function (index, view) {
|
||||
$("#dialog_manageviews-table").append("<tr id=\"manageviews_tr_" + view[0] + "\"><td>" + view[1] + "</td><td><button id=\"button_edit_" + view[0] + "\" class=\"button_edit\"> </button></td><td><button class=\"button_delete\" id=\"button_edit_" + view[0] + "\"> </button></td></tr>");
|
||||
});
|
||||
$(".button_edit").button({
|
||||
icons: {
|
||||
primary: "ui-icon-pencil"
|
||||
},
|
||||
text: false
|
||||
});
|
||||
$(".button_delete").button({
|
||||
icons: {
|
||||
primary: "ui-icon-trash"
|
||||
},
|
||||
text: false
|
||||
});
|
||||
$(".button_delete").click(function (ui) {
|
||||
var sichtName = $(ui.currentTarget.parentNode.parentNode.firstChild).html();
|
||||
delete_view_id = $(ui.currentTarget).attr("id").substr(12);
|
||||
$("#label_deleteview").html(sichtName);
|
||||
$("#dialog_deleteview").dialog("open");
|
||||
return false;
|
||||
});
|
||||
$(".button_edit").click(function (ui) {
|
||||
edit_view_name = $(ui.currentTarget.parentNode.parentNode.firstChild).html();
|
||||
edit_view_id = $(ui.currentTarget).attr("id").substr(12);
|
||||
$("#dialog_editview_name").val(edit_view_name);
|
||||
$("#dialog_editview").dialog("open");
|
||||
return false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$("#dialog_settings").dialog({
|
||||
autoOpen: false,
|
||||
resizable: true,
|
||||
height: 500,
|
||||
width: 600,
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Speichern": function () {
|
||||
$("#dialog_settings_loading").show();
|
||||
console.log("update widget refresh interval");
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/global/setRefreshTime",
|
||||
data: "interval=" + $("#dialog_settings_intervall").val(),
|
||||
context: document.body,
|
||||
success: function () {
|
||||
refreshTime = $("#dialog_settings_intervall").val();
|
||||
$("#dialog_settings_loading").hide();
|
||||
$("#dialog_settings").dialog("close");
|
||||
}
|
||||
});
|
||||
$(this).dialog("close");
|
||||
},
|
||||
"Abbrechen": function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
},
|
||||
open: function (event, ui) {
|
||||
console.log("dialog settings opened");
|
||||
$("#dialog_settings_loading").show();
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: true,
|
||||
url: "../../ajax/global/getRefreshTime",
|
||||
data: "interval=" + $("#dialog_settings_intervall").val(),
|
||||
context: document.body,
|
||||
success: function (refreshInterval) {
|
||||
$("#dialog_settings_intervall").val(refreshInterval);
|
||||
$("#dialog_settings_loading").hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
181
fhem/contrib/YAF/YAF/www/yaf.htm
Executable file
@ -0,0 +1,181 @@
|
||||
<!--
|
||||
########################################################################################
|
||||
#
|
||||
# yaf.htm
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
-->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="us" lang="us">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>YAF GUI</title>
|
||||
<link type="text/css" href="css/smoothness/jquery-ui-1.9.1.custom.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="css/yaf.css" rel="stylesheet" />
|
||||
<script type="text/javascript" src="js/jquery-1.8.2.js"></script>
|
||||
<script type="text/javascript" src="js/jquery-ui-1.9.1.custom.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.ui.touch-punch.min.js"></script>
|
||||
<script type="text/javascript" src="js/yaf-dialogs.js"></script>
|
||||
<script type="text/javascript" src="js/yaf-basics.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
// Array mit den Namen und den zugehörigen Id's der Sichten
|
||||
var views = new Array();
|
||||
var widgets = new Array();
|
||||
var current_view_id = null;
|
||||
var current_widget_id = null;
|
||||
var refreshTime = null;
|
||||
|
||||
// Modus in der Sich YAF befindet
|
||||
// modus=0: Live Modus
|
||||
// modus=1: Positionierungs Modus
|
||||
var view_mode = 0;
|
||||
var widgetWasMoved = false;
|
||||
var close_widget_menue = true;
|
||||
|
||||
// Speichert die Id der View, die gelöscht werden soll
|
||||
var delete_view_id = null;
|
||||
var edit_view_name = null;
|
||||
var edit_view_id = null;
|
||||
var add_widget_name = null;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Initialisiert die Oberfläche
|
||||
function init() {
|
||||
init_tabs();
|
||||
init_menue();
|
||||
$("#widget_menue").hide();
|
||||
init_dialogs();
|
||||
init_handlers();
|
||||
load_views(show_views);
|
||||
init_RefreshWidgets();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
###widget_js###
|
||||
|
||||
$(document).ready(function() {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
###widget_css###
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="menue">
|
||||
<div class="menue_block">
|
||||
<button id="button_back" class="menue_button">Zu FHEM</button>
|
||||
</div>
|
||||
<div class="menue_block">
|
||||
<button id="button_settings" class="menue_button">Einstellungen</button>
|
||||
</div>
|
||||
<div class="menue_block">
|
||||
<button id="button_addview" class="menue_button">Sicht hinzufügen</button>
|
||||
<button id="button_manageviews" class="menue_button">Sichten verwalten</button>
|
||||
</div>
|
||||
<div class="menue_block">
|
||||
<button id="button_addwidget" class="menue_button">Widget hinzufügen</button>
|
||||
</div>
|
||||
<div class="menue_block">
|
||||
<div id="button_editview" class="menue_button">
|
||||
<input type="radio" id="button_switchmode_0" name="radio" checked="checked"/><label for="button_switchmode_0" style="width: 118px;">Live</label>
|
||||
<input type="radio" id="button_switchmode_1" name="radio"/><label for="button_switchmode_1" style="width: 118px;">Bearbeiten</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="tabs">
|
||||
<div id="widget_menue">
|
||||
<button id="widget_menue_edit" class="widget_menue"></button>
|
||||
<button id="widget_menue_delete" class="widget_menue"></button>
|
||||
</div>
|
||||
<div id="tabs_error"></div>
|
||||
<ul id="views">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="dialog_addview" title="Sicht hinzufügen">
|
||||
<div class="loading_animation" id="dialog_addview_loading"></div>
|
||||
<p>Hier können Sie YAF eine neue Sicht hinzufügen.</p>
|
||||
<label>Name: </label><input id="dialog_addview_name" name="dialog_addview_name"/>
|
||||
</div>
|
||||
|
||||
<div id="dialog_editview" title="Sicht bearbeiten">
|
||||
<div class="loading_animation" id="dialog_addview_loading"></div>
|
||||
<p>Hier können Sie die bestehende Sicht ändern.</p>
|
||||
<label>Name: </label><input id="dialog_editview_name" name="dialog_editview_name" value="" />
|
||||
</div>
|
||||
|
||||
<div id="dialog_deleteview" title="Sicht löschen">
|
||||
<div class="loading_animation" id="dialog_deleteview_loading"></div>
|
||||
<p>Sind Sie sicher, dass Sie die Sicht "<span><b id="label_deleteview"></b></span>" löschen Möchten? Es gehen alle Widgets verloren, die auf dieser Sicht verankert sind!</p>
|
||||
</div>
|
||||
|
||||
<div id="dialog_manageviews" title="Sichten verwalten">
|
||||
<div class="loading_animation" id="dialog_manageviews_loading"></div>
|
||||
<p>Hier können Sie einzelne Sichten löschen oder bearbeiten. Gelöschte Sichten können nicht wiederhergestellt werden!</p>
|
||||
<table id="dialog_manageviews-table">
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="dialog_addwidget" title="Widget hinzufügen">
|
||||
<div class="loading_animation" id="dialog_addwidget_loading"></div>
|
||||
<p>Hier können Sie Widgets zur ausgewählten Sicht hinzufügen.</p>
|
||||
<table id="dialog_addwidget_table">
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="dialog_addwidget_setup" title="Widget hinzufügen">
|
||||
<div class="loading_animation" id="dialog_addwidget_setup_loading"></div>
|
||||
<p>Widget vom Typ <b id="dialog_addwidget_setup_widget"></b> hinzufügen: </p>
|
||||
<div id="dialog_addwidget_setup_form" />
|
||||
</div>
|
||||
|
||||
<div id="dialog_editwidget" title="Widget bearbeiten">
|
||||
<div class="loading_animation" id="dialog_editwidget_loading"></div>
|
||||
<p>Widget "<span><b id="label_editwidget"></b></span>" bearbeiten:</p>
|
||||
</div>
|
||||
|
||||
<div id="dialog_deletewidget" title="Widget löschen">
|
||||
<div class="loading_animation" id="dialog_deletewidget_loading"></div>
|
||||
<p>Sind Sie sicher, dass Sie das Widget "<span><b id="label_deletewidget"></b></span>" löschen möchten?</p>
|
||||
</div>
|
||||
|
||||
<div id="dialog_settings" title="Einstellungen">
|
||||
<div class="loading_animation" id="dialog_settings_loading"></div>
|
||||
<p>Einstellungen</p>
|
||||
<label>Refresh-Intervall: </label><input id="dialog_settings_intervall" name="dialog_settings_intervall" value="" />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
98
fhem/contrib/YAF/YAF/xml/xmlSchema.xsd
Normal file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
########################################################################################
|
||||
#
|
||||
# xmlSchema.xsd
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
-->
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- declaration of root -->
|
||||
<xsd:element name="configuration" type="configuration-type" />
|
||||
|
||||
<xsd:complexType name="configuration-type">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="settings" type="settings-type" minOccurs="1" maxOccurs="1" />
|
||||
<xsd:element name="views" type="views-type" minOccurs="1" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<!-- settings -->
|
||||
<xsd:complexType name="settings-type">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="refresh" minOccurs="1" maxOccurs="1">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="interval" type="xsd:int" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<!-- views -->
|
||||
<xsd:complexType name="views-type">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="view" type="view-type" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="view-type">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="backgrounds" type="backgrounds-type" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="widgets" type="widgets-type" minOccurs="1" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="backgrounds-type">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="background" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="img_url" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="x_pos" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="y_pos" type="xsd:int" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="widgets-type">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="widget" type="widget-type" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="widget-type">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="attr" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="value" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="id" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="x_pos" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="y_pos" type="xsd:int" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
54
fhem/contrib/YAF/YAF/xml/yafConfig.xml.example
Executable file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
########################################################################################
|
||||
#
|
||||
# yafConfig.xml
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee
|
||||
#
|
||||
########################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
########################################################################################
|
||||
-->
|
||||
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xmlSchema.xsd">
|
||||
<settings>
|
||||
<refresh interval="5"/>
|
||||
</settings>
|
||||
<views>
|
||||
<view id="1" name="Erdgeschoss">
|
||||
<backgrounds>
|
||||
<background img_url="./img/eg.jpeg" x_pos="1" y_pos="1"/>
|
||||
</backgrounds>
|
||||
<widgets>
|
||||
<widget name="fs20easylamp" x_pos="308" y_pos="202" id="1">
|
||||
<attr name="fhemname" value="ez_LichtRegal"/>
|
||||
</widget>
|
||||
</widgets>
|
||||
</view>
|
||||
<view id="2" name="Obergeschoss">
|
||||
<backgrounds>
|
||||
<background img_url="./img/1og.jpeg" x_pos="1" y_pos="1"/>
|
||||
</backgrounds>
|
||||
<widgets>
|
||||
<widget name="fs20easylamp" x_pos="151" y_pos="279" id="1">
|
||||
<attr name="fhemname" value="ez_LichtRegal2"/>
|
||||
</widget>
|
||||
</widgets>
|
||||
</view>
|
||||
</views>
|
||||
</configuration>
|
88
fhem/contrib/YAF/fhem.cfg
Normal file
@ -0,0 +1,88 @@
|
||||
################################################################################
|
||||
#
|
||||
# fhem.cfg
|
||||
# Exemplary fhem.cfg for demonstration purposes.
|
||||
# Defines YAF and Floorplan and demonstrates the binding between the lamp widgets
|
||||
# This file is not copied to /opt/fhem during the installation process!
|
||||
#
|
||||
# YAF - Yet Another Floorplan
|
||||
# FHEM Projektgruppe Hochschule Karlsruhe, 2013
|
||||
# Markus Mangei, Daniel Weisensee
|
||||
#
|
||||
################################################################################
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
attr global logfile ./log/fhem-%Y-%m.log
|
||||
attr global modpath . # where our FHEM directory is
|
||||
attr global statefile ./log/fhem.save # where to save the state of the devices
|
||||
attr global verbose 3 # "normal" verbosity (min 1, max 5)
|
||||
attr global motd none
|
||||
|
||||
define telnetPort telnet 7072 global # our TCP/IP port
|
||||
|
||||
define WEB FHEMWEB 8083 global
|
||||
define WEBphone FHEMWEB 8084 global
|
||||
attr WEBphone smallscreen
|
||||
|
||||
define WEBtablet FHEMWEB 8085 global
|
||||
attr WEBtablet touchpad
|
||||
|
||||
# Fake FileLog entry, to access the fhem log from FHEMWEB
|
||||
define Logfile FileLog ./log/fhem-%Y-%m.log fakelog
|
||||
|
||||
define autocreate autocreate
|
||||
attr autocreate autosave
|
||||
attr autocreate device_room %TYPE
|
||||
attr autocreate filelog ./log/%NAME-%Y.log
|
||||
attr autocreate weblink
|
||||
attr autocreate weblink_room Plots
|
||||
|
||||
# Disable this to avoid looking for new USB devices on startup
|
||||
define initialUsbCheck notify global:INITIALIZED usb create
|
||||
|
||||
|
||||
# If the above notify did not helped, then you probably have to enable some of
|
||||
# the following lines. Verify first that /dev/xxx ist correct.
|
||||
|
||||
#define FHZ FHZ /dev/USB0
|
||||
#define CUL CUL /dev/ttyACM0@9600 1234
|
||||
#attr CUL rfmode HomeMatic
|
||||
|
||||
#define EUL TCM 310 /dev/ttyACM0@57600
|
||||
#define BscBor TCM 120 /dev/ttyUSB0@9600
|
||||
#define BscSmartConnect TCM 310 /dev/ttyUSB0@57600
|
||||
|
||||
################################################################################
|
||||
# [YAF project] Configure YAF - Yet Another Floorplan
|
||||
################################################################################
|
||||
define yafVar YAF
|
||||
|
||||
################################################################################
|
||||
# [YAF project] Configure Floorplan
|
||||
################################################################################
|
||||
define Erdgeschoss FLOORPLAN
|
||||
attr Erdgeschoss fp_arrange 1
|
||||
|
||||
define ez_LichtRegal FS20 6969 01
|
||||
attr ez_LichtRegal fp_Erdgeschoss 194,384,0,
|
||||
attr ez_LichtRegal model fs20st
|
||||
attr ez_LichtRegal room Schlafen
|
||||
|
||||
define ez_LichtRegal2 FS20 6969 02
|
||||
attr ez_LichtRegal2 fp_Erdgeschoss 59,580,0,
|
||||
attr ez_LichtRegal2 model fs20st
|
||||
attr ez_LichtRegal2 room Bad
|