Merge branch 'master' into add_v4l

Former-commit-id: b3f1d532c6145ba80c161b18214de6efbc55ff7b
This commit is contained in:
johan 2014-01-11 13:00:51 +01:00
commit fdb140c1ae
82 changed files with 2122 additions and 5280 deletions

View File

@ -8,7 +8,10 @@ cmake_minimum_required(VERSION 2.8)
# set the build options # set the build options
option (ENABLE_DISPMANX "Enable the RPi dispmanx grabber" ON) option (ENABLE_DISPMANX "Enable the RPi dispmanx grabber" ON)
option (ENABLE_SPIDEV "Enable the SPIDEV device" ON)
message(STATUS "ENABLE_DISPMANX = " ${ENABLE_DISPMANX}) message(STATUS "ENABLE_DISPMANX = " ${ENABLE_DISPMANX})
message(STATUS "ENABLE_SPIDEV = " ${ENABLE_SPIDEV})
option (ENABLE_V4L2 "Enable the V4L2 grabber" ON) option (ENABLE_V4L2 "Enable the V4L2 grabber" ON)
message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2}) message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2})
@ -42,13 +45,18 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
set(CMAKE_BUILD_TYPE "Release") set(CMAKE_BUILD_TYPE "Release")
# enable C++11 # enable C++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -g") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++11 -Wall")
# Configure the use of QT4 # Configure the use of QT4
find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED QUIET) find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED QUIET)
# add protocol buffers # add protocol buffers (make sure to find the static version)
set(CMAKE_FIND_LIBRARY_SUFFIXES_OLD ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
find_package(Protobuf REQUIRED) find_package(Protobuf REQUIRED)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_OLD})
set(CMAKE_FIND_LIBRARY_SUFFIXES_OLD)
#add libusb and pthreads #add libusb and pthreads
find_package(libusb-1.0 REQUIRED) find_package(libusb-1.0 REQUIRED)
@ -56,7 +64,10 @@ find_package(Threads REQUIRED)
include(${QT_USE_FILE}) include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS}) add_definitions(${QT_DEFINITIONS})
link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf) # TODO[TvdZ]: This linking directory should only be added if we are cross compiling
if(NOT APPLE)
link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
endif()
configure_file(bin/install_hyperion.sh ${LIBRARY_OUTPUT_PATH} @ONLY) configure_file(bin/install_hyperion.sh ${LIBRARY_OUTPUT_PATH} @ONLY)
configure_file(config/hyperion.config.json ${LIBRARY_OUTPUT_PATH} @ONLY) configure_file(config/hyperion.config.json ${LIBRARY_OUTPUT_PATH} @ONLY)

View File

@ -5,3 +5,6 @@
// Define to enable the v4l2 grabber // Define to enable the v4l2 grabber
#cmakedefine ENABLE_V4L2 #cmakedefine ENABLE_V4L2
// Define to enable the spi-device
#cmakedefine ENABLE_SPIDEV

View File

@ -18,10 +18,12 @@ tar --create --verbose --gzip --absolute-names --show-transformed-names \
--transform "s:$builddir/bin/:hyperion/bin/:" \ --transform "s:$builddir/bin/:hyperion/bin/:" \
--transform "s:$repodir/effects/:hyperion/effects/:" \ --transform "s:$repodir/effects/:hyperion/effects/:" \
--transform "s:$repodir/config/:hyperion/config/:" \ --transform "s:$repodir/config/:hyperion/config/:" \
--transform "s:$repodir/bin/hyperion.init.sh:hyperion/init.d/hyperion.init.sh:" \
--transform "s://:/:g" \ --transform "s://:/:g" \
"$builddir/bin/hyperiond" \ "$builddir/bin/hyperiond" \
"$builddir/bin/hyperion-remote" \ "$builddir/bin/hyperion-remote" \
"$builddir/bin/gpio2spi" \ "$builddir/bin/gpio2spi" \
"$builddir/bin/dispmanx2png" \ "$builddir/bin/dispmanx2png" \
"$repodir/effects/"* \ "$repodir/effects/"* \
"$repodir/bin/hyperion.init.sh" \
"$repodir/config/hyperion.config.json" "$repodir/config/hyperion.config.json"

62
bin/hyperion.init.sh Normal file
View File

@ -0,0 +1,62 @@
#!/bin/bash
# Hyperion daemon
# description: Hyperion daemon
# processname: hyperiond
DAEMON=hyperiond
DAEMONOPTS="/etc/hyperion.config.json"
DAEMON_PATH="/usr/bin"
NAME=$DEAMON
DESC="Hyperion ambilight server"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
case "$1" in
start)
printf "%-50s" "Starting $NAME..."
cd $DAEMON_PATH
PID=`$DAEMON $DAEMONOPTS > /dev/null 2>&1 & echo $!`
#echo "Saving PID" $PID " to " $PIDFILE
if [ -z $PID ]; then
printf "%s\n" "Fail"
else
echo $PID > $PIDFILE
printf "%s\n" "Ok"
fi
;;
status)
printf "%-50s" "Checking $NAME..."
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
printf "%s\n" "Process dead but pidfile exists"
else
echo "Running"
fi
else
printf "%s\n" "Service not running"
fi
;;
stop)
printf "%-50s" "Stopping $NAME"
PID=`cat $PIDFILE`
cd $DAEMON_PATH
if [ -f $PIDFILE ]; then
kill -HUP $PID
printf "%s\n" "Ok"
rm -f $PIDFILE
else
printf "%s\n" "pidfile not found"
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {status|start|stop|restart}"
exit 1
esac

View File

@ -1,12 +1,21 @@
#!/bin/sh #!/bin/sh
# Make sure /sbin is on the path (for service to find sub scripts)
PATH="/sbin:$PATH"
# Script for downloading and installing the latest Hyperion release # Script for downloading and installing the latest Hyperion release
# Find out if we are on XBian # Find out if we are on Raspbmc
IS_XBIAN=`cat /etc/issue | grep XBian | wc -l` IS_XBIAN=`cat /etc/issue | grep XBian | wc -l`
IS_RASPBMC=`cat /etc/issue | grep Raspbmc | wc -l`
IS_OPENELEC=`cat /etc/issue | grep -m 1 OpenELEC | wc -l`
# check which init script we should use
USE_INITCTL=`which /sbin/initctl | wc -l`
USE_SERVICE=`which /usr/sbin/service | wc -l`
# Make sure that the boblight daemon is no longer running # Make sure that the boblight daemon is no longer running
BOBLIGHT_PROCNR=$(ps -e | grep "boblight" | wc -l) BOBLIGHT_PROCNR=$(pidof boblightd | wc -l)
if [ $BOBLIGHT_PROCNR -eq 1 ]; if [ $BOBLIGHT_PROCNR -eq 1 ];
then then
echo 'Found running instance of boblight. Please stop boblight via XBMC menu before installing hyperion' echo 'Found running instance of boblight. Please stop boblight via XBMC menu before installing hyperion'
@ -14,29 +23,73 @@ then
fi fi
# Stop hyperion daemon if it is running # Stop hyperion daemon if it is running
/sbin/initctl stop hyperion # Start the hyperion daemon
if [ $USE_INITCTL -eq 1 ]; then
/sbin/initctl stop hyperion
elif [ $USE_SERVICE -eq 1 ]; then
/usr/sbin/service hyperion stop
fi
# Get and extract the Hyperion binaries and effects to /opt # Get and extract the Hyperion binaries and effects
wget https://raw.github.com/tvdzwan/hyperion/master/deploy/hyperion.tar.gz -O - | tar -C /opt -xz echo 'Downloading hyperion'
if [ $IS_OPENELEC -eq 1 ]; then
# OpenELEC has a readonly file system. Use alternative location
curl --get https://raw.github.com/tvdzwan/hyperion/master/deploy/hyperion.tar.gz | tar -C /storage -xz
curl --get https://raw.github.com/tvdzwan/hyperion/master/deploy/hyperion.deps.openelec-rpi.tar.gz | tar -C /storage/hyperion/bin -xz
# modify the default config to have a correct effect path
sed -i 's:/opt:/storage:g' /storage/hyperion/config/hyperion.config.json
else
wget https://raw.github.com/tvdzwan/hyperion/master/deploy/hyperion.tar.gz -O - | tar -C /opt -xz
fi
# create links to the binaries # create links to the binaries
ln -fs /opt/hyperion/bin/hyperiond /usr/bin/hyperiond if [ $IS_OPENELEC -ne 1 ]; then
ln -fs /opt/hyperion/bin/hyperion-remote /usr/bin/hyperion-remote ln -fs /opt/hyperion/bin/hyperiond /usr/bin/hyperiond
ln -fs /opt/hyperion/bin/hyperion-remote /usr/bin/hyperion-remote
fi
# create link to the gpio changer (gpio->spi) # create link to the gpio changer (gpio->spi)
if [ $IS_XBIAN -eq 0 ]; then if [ $IS_RASPBMC -eq 1 ]; then
ln -fs /opt/hyperion/bin/gpio2spi /usr/bin/gpio2spi ln -fs /opt/hyperion/bin/gpio2spi /usr/bin/gpio2spi
fi fi
# Copy a link to the hyperion configuration file to /etc # Copy a link to the hyperion configuration file to /etc
ln -s /opt/hyperion/config/hyperion.config.json /etc/hyperion.config.json if [ $IS_OPENELEC -eq 1 ]; then
# copy to alternate location, because of readonly file system
# /storage/.config is available as samba share. A symbolic link would not be working
false | cp -i /storage/hyperion/config/hyperion.config.json /storage/.config/hyperion.config.json 2>/dev/null
else
ln -s /opt/hyperion/config/hyperion.config.json /etc/hyperion.config.json
fi
# Copy the service control configuration to /etc/int # Copy the service control configuration to /etc/int
if [ $IS_XBIAN -eq 0 ]; then if [ $USE_INITCTL -eq 1 ]; then
wget -N https://raw.github.com/tvdzwan/hyperion/master/deploy/hyperion.conf -P /etc/init/ echo 'Installing initctl script'
else if [ $IS_RASPBMC -eq 1 ]; then
wget -N https://raw.github.com/tvdzwan/hyperion/master/deploy/hyperion.xbian.conf -O /etc/init/hyperion.conf wget -N https://raw.github.com/tvdzwan/hyperion/master/deploy/hyperion.conf -P /etc/init/
else
wget -N https://raw.github.com/tvdzwan/hyperion/master/deploy/hyperion.xbian.conf -O /etc/init/hyperion.conf
fi
elif [ $USE_SERVICE -eq 1 ]; then
echo 'Installing startup script in init.d'
# place startup script in init.d and add it to upstart
ln -fs /opt/hyperion/init.d/hyperion.init.sh /etc/init.d/hyperion
chmod +x /etc/init.d/hyperion
update-rc.d hyperion defaults 98 02
elif [ $IS_OPENELEC -eq 1 ]; then
# only add to start script if hyperion is not present yet
if [ `cat /storage/.config/autostart.sh 2>/dev/null | grep hyperiond | wc -l` -eq 0 ]; then
echo 'Adding Hyperion to autostart script'
echo "/storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion.config.json > /dev/null 2>&1 &" >> /storage/.config/autostart.sh
chmod +x /storage/.config/autostart.sh
fi
fi fi
# Start the hyperion daemon # Start the hyperion daemon
/sbin/initctl start hyperion if [ $USE_INITCTL -eq 1 ]; then
/sbin/initctl start hyperion
elif [ $USE_SERVICE -eq 1 ]; then
/usr/sbin/service hyperion start
fi

View File

@ -0,0 +1,21 @@
# -----------------------------------------------------------------------------
# Find IOKit framework (Mac OS X).
#
# Define:
# CoreFoundation_FOUND
# CoreFoundation_INCLUDE_DIR
# CoreFoundation_LIBRARY
set(CoreFoundation_FOUND false)
set(CoreFoundation_INCLUDE_DIR)
set(CoreFoundation_LIBRARY)
if(APPLE)
# The only platform it makes sense to check for CoreFoundation
find_library(CoreFoundation CoreFoundation)
if(CoreFoundation)
set(CoreFoundation_FOUND true)
set(CoreFoundation_INCLUDE_DIR ${CoreFoundation})
set(CoreFoundation_LIBRARY ${CoreFoundation})
endif(CoreFoundation)
endif(APPLE)

21
cmake/FindIOKit.cmake Normal file
View File

@ -0,0 +1,21 @@
# -----------------------------------------------------------------------------
# Find IOKit framework (Mac OS X).
#
# Define:
# IOKit_FOUND
# IOKit_INCLUDE_DIR
# IOKit_LIBRARY
set(IOKit_FOUND false)
set(IOKit_INCLUDE_DIR)
set(IOKit_LIBRARY)
if(APPLE)
# The only platform it makes sense to check for IOKit
find_library(IOKit IOKit)
if(IOKit)
set(IOKit_FOUND true)
set(IOKit_INCLUDE_DIR ${IOKit})
set(IOKit_LIBRARY ${IOKit})
endif(IOKit)
endif(APPLE)

View File

@ -1,16 +1,37 @@
project(hidapi) project(hidapi)
#add libusb and pthreads # Add the 'generic' hidapi include directory
find_package(libusb-1.0 REQUIRED) include_directories(../../include/hidapi)
find_package(Threads REQUIRED)
include_directories( #TODO[TvdZ]: Rename hidapi-??? to hidapi
../../include/hidapi if(APPLE)
${LIBUSB_1_INCLUDE_DIRS})
add_library(hidapi-libusb hid-libusb.c) find_package(IOKit REQUIRED)
find_package(CoreFoundation REQUIRED)
target_link_libraries(hidapi-libusb include_directories($IOKit_INCLUDE_DIRS})
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev include_directories($CoreFoundation_INCLUDE_DIRS})
${CMAKE_THREAD_LIBS_INIT}
) # HIDAPI library specific for MacOS
add_library(hidapi-mac hid-mac.c)
target_link_libraries(hidapi-mac
${IOKit_LIBRARY}
${CoreFoundation_LIBRARY})
elseif(UNIX)
# HIDAPI library based on lib-usb
#add libusb and pthreads
find_package(libusb-1.0 REQUIRED)
find_package(Threads REQUIRED)
include_directories(${LIBUSB_1_INCLUDE_DIRS})
add_library(hidapi-libusb hid-libusb.c)
target_link_libraries(hidapi-libusb
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev
${CMAKE_THREAD_LIBS_INIT}
)
endif()

1112
dependencies/build/hidapi/hid-mac.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
4d50c38a61c9f32a15b29ef3b3953c2835fa9cac

View File

@ -1 +1 @@
27dcc318ae9a9226676fb33626500e57703d7b6d 69287788649383ba7926e315debc69b7f4bd82a0

View File

@ -57,7 +57,6 @@ target_link_libraries(hyperion
hyperion-utils hyperion-utils
leddevice leddevice
effectengine effectengine
hidapi-libusb
serialport serialport
${QT_LIBRARIES} ${QT_LIBRARIES}
) )

View File

@ -1,6 +1,7 @@
// STL includes // STL includes
#include <algorithm> #include <algorithm>
#include <cmath>
#include <cassert> #include <cassert>
// hyperion includes // hyperion includes

View File

@ -7,9 +7,6 @@
// Qt includes // Qt includes
#include <QTimer> #include <QTimer>
// Linux-SPI includes
#include <linux/spi/spidev.h>
// hyperion incluse // hyperion incluse
#include <leddevice/LedDevice.h> #include <leddevice/LedDevice.h>

View File

@ -20,38 +20,52 @@ SET(Leddevice_HEADERS
${CURRENT_HEADER_DIR}/LedDevice.h ${CURRENT_HEADER_DIR}/LedDevice.h
${CURRENT_HEADER_DIR}/LedDeviceFactory.h ${CURRENT_HEADER_DIR}/LedDeviceFactory.h
${CURRENT_SOURCE_DIR}/LedSpiDevice.h
${CURRENT_SOURCE_DIR}/LedRs232Device.h ${CURRENT_SOURCE_DIR}/LedRs232Device.h
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
${CURRENT_SOURCE_DIR}/LedDeviceSedu.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2811.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2812b.h
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.h
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.h
${CURRENT_SOURCE_DIR}/LedDeviceLightpack.h ${CURRENT_SOURCE_DIR}/LedDeviceLightpack.h
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.h
${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.h ${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.h
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.h
${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.h
${CURRENT_SOURCE_DIR}/LedDeviceSedu.h
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2812b.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2811.h
) )
SET(Leddevice_SOURCES SET(Leddevice_SOURCES
${CURRENT_SOURCE_DIR}/LedDeviceFactory.cpp ${CURRENT_SOURCE_DIR}/LedDeviceFactory.cpp
${CURRENT_SOURCE_DIR}/LedSpiDevice.cpp
${CURRENT_SOURCE_DIR}/LedRs232Device.cpp ${CURRENT_SOURCE_DIR}/LedRs232Device.cpp
${CURRENT_SOURCE_DIR}/LedDeviceSedu.cpp
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2811.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2812b.cpp
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.cpp
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.cpp
${CURRENT_SOURCE_DIR}/LedDeviceAdalight.cpp ${CURRENT_SOURCE_DIR}/LedDeviceAdalight.cpp
${CURRENT_SOURCE_DIR}/LedDeviceLightpack.cpp ${CURRENT_SOURCE_DIR}/LedDeviceLightpack.cpp
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.cpp
${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.cpp ${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.cpp
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.cpp
${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.cpp
${CURRENT_SOURCE_DIR}/LedDeviceSedu.cpp
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2811.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2812b.cpp
) )
if(ENABLE_SPIDEV)
SET(Leddevice_HEADERS
${Leddevice_HEADERS}
${CURRENT_SOURCE_DIR}/LedSpiDevice.h
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.h
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
)
SET(Leddevice_SOURCES
${Leddevice_SOURCES}
${CURRENT_SOURCE_DIR}/LedSpiDevice.cpp
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.cpp
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
)
endif(ENABLE_SPIDEV)
QT4_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS}) QT4_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS})
add_library(leddevice add_library(leddevice
@ -63,9 +77,13 @@ add_library(leddevice
target_link_libraries(leddevice target_link_libraries(leddevice
hyperion-utils hyperion-utils
hidapi-libusb
serialport serialport
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev ${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${QT_LIBRARIES} ${QT_LIBRARIES}
) )
if(APPLE)
target_link_libraries(leddevice hidapi-mac)
else()
target_link_libraries(leddevice hidapi-libusb)
endif()

View File

@ -1,19 +1,26 @@
// Build configuration
#include <HyperionConfig.h>
// Leddevice includes // Leddevice includes
#include <leddevice/LedDeviceFactory.h> #include <leddevice/LedDeviceFactory.h>
// Local Leddevice includes // Local Leddevice includes
#include "LedDeviceLpd6803.h" #ifdef ENABLE_SPIDEV
#include "LedDeviceLpd8806.h" #include "LedDeviceLpd6803.h"
#include "LedDeviceSedu.h" #include "LedDeviceLpd8806.h"
#include "LedDeviceTest.h" #include "LedDeviceWs2801.h"
#include "LedDeviceWs2801.h" #endif
#include "LedDeviceWs2811.h"
#include "LedDeviceWs2812b.h"
#include "LedDeviceAdalight.h" #include "LedDeviceAdalight.h"
#include "LedDevicePaintpack.h"
#include "LedDeviceLightpack.h" #include "LedDeviceLightpack.h"
#include "LedDeviceMultiLightpack.h" #include "LedDeviceMultiLightpack.h"
#include "LedDevicePaintpack.h"
#include "LedDevicePiBlaster.h"
#include "LedDeviceSedu.h"
#include "LedDeviceTest.h"
#include "LedDeviceWs2811.h"
#include "LedDeviceWs2812b.h"
LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
{ {
@ -23,40 +30,18 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
std::transform(type.begin(), type.end(), type.begin(), ::tolower); std::transform(type.begin(), type.end(), type.begin(), ::tolower);
LedDevice* device = nullptr; LedDevice* device = nullptr;
if (type == "ws2801" || type == "lightberry") if (false) {}
else if (type == "adalight")
{ {
const std::string output = deviceConfig["output"].asString(); const std::string output = deviceConfig["output"].asString();
const unsigned rate = deviceConfig["rate"].asInt(); const unsigned rate = deviceConfig["rate"].asInt();
LedDeviceWs2801* deviceWs2801 = new LedDeviceWs2801(output, rate); LedDeviceAdalight* deviceAdalight = new LedDeviceAdalight(output, rate);
deviceWs2801->open(); deviceAdalight->open();
device = deviceWs2801; device = deviceAdalight;
} }
else if (type == "ws2812b") #ifdef ENABLE_SPIDEV
{
LedDeviceWs2812b * deviceWs2812b = new LedDeviceWs2812b();
deviceWs2812b->open();
device = deviceWs2812b;
}
// else if (type == "ws2811")
// {
// const std::string output = deviceConfig["output"].asString();
// const std::string outputSpeed = deviceConfig["output"].asString();
// const std::string timingOption = deviceConfig["timingOption"].asString();
// ws2811::SpeedMode speedMode = (outputSpeed == "high")? ws2811::highspeed : ws2811::lowspeed;
// if (outputSpeed != "high" && outputSpeed != "low")
// {
// std::cerr << "Incorrect speed-mode selected for WS2811: " << outputSpeed << " != {'high', 'low'}" << std::endl;
// }
// LedDeviceWs2811 * deviceWs2811 = new LedDeviceWs2811(output, ws2811::fromString(timingOption, ws2811::option_2855), speedMode);
// deviceWs2811->open();
// device = deviceWs2811;
// }
else if (type == "lpd6803" || type == "ldp6803") else if (type == "lpd6803" || type == "ldp6803")
{ {
const std::string output = deviceConfig["output"].asString(); const std::string output = deviceConfig["output"].asString();
@ -77,26 +62,34 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
device = deviceLpd8806; device = deviceLpd8806;
} }
else if (type == "sedu") else if (type == "ws2801" || type == "lightberry")
{ {
const std::string output = deviceConfig["output"].asString(); const std::string output = deviceConfig["output"].asString();
const unsigned rate = deviceConfig["rate"].asInt(); const unsigned rate = deviceConfig["rate"].asInt();
LedDeviceSedu* deviceSedu = new LedDeviceSedu(output, rate); LedDeviceWs2801* deviceWs2801 = new LedDeviceWs2801(output, rate);
deviceSedu->open(); deviceWs2801->open();
device = deviceSedu; device = deviceWs2801;
} }
else if (type == "adalight") #endif
{ // else if (type == "ws2811")
const std::string output = deviceConfig["output"].asString(); // {
const unsigned rate = deviceConfig["rate"].asInt(); // const std::string output = deviceConfig["output"].asString();
// const std::string outputSpeed = deviceConfig["output"].asString();
// const std::string timingOption = deviceConfig["timingOption"].asString();
LedDeviceAdalight* deviceAdalight = new LedDeviceAdalight(output, rate); // ws2811::SpeedMode speedMode = (outputSpeed == "high")? ws2811::highspeed : ws2811::lowspeed;
deviceAdalight->open(); // if (outputSpeed != "high" && outputSpeed != "low")
// {
// std::cerr << "Incorrect speed-mode selected for WS2811: " << outputSpeed << " != {'high', 'low'}" << std::endl;
// }
device = deviceAdalight; // LedDeviceWs2811 * deviceWs2811 = new LedDeviceWs2811(output, ws2811::fromString(timingOption, ws2811::option_2855), speedMode);
} // deviceWs2811->open();
// device = deviceWs2811;
// }
else if (type == "lightpack") else if (type == "lightpack")
{ {
const std::string output = deviceConfig.get("output", "").asString(); const std::string output = deviceConfig.get("output", "").asString();
@ -106,6 +99,13 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
device = deviceLightpack; device = deviceLightpack;
} }
else if (type == "multi-lightpack")
{
LedDeviceMultiLightpack* deviceLightpack = new LedDeviceMultiLightpack();
deviceLightpack->open();
device = deviceLightpack;
}
else if (type == "paintpack") else if (type == "paintpack")
{ {
LedDevicePaintpack * devicePainLightpack = new LedDevicePaintpack(); LedDevicePaintpack * devicePainLightpack = new LedDevicePaintpack();
@ -113,18 +113,38 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
device = devicePainLightpack; device = devicePainLightpack;
} }
else if (type == "multi-lightpack") else if (type == "piblaster")
{ {
LedDeviceMultiLightpack* deviceLightpack = new LedDeviceMultiLightpack(); const std::string output = deviceConfig.get("output", "").asString();
deviceLightpack->open(); const std::string assignment = deviceConfig.get("assignment", "").asString();
device = deviceLightpack; LedDevicePiBlaster * devicePiBlaster = new LedDevicePiBlaster(output, assignment);
devicePiBlaster->open();
device = devicePiBlaster;
}
else if (type == "sedu")
{
const std::string output = deviceConfig["output"].asString();
const unsigned rate = deviceConfig["rate"].asInt();
LedDeviceSedu* deviceSedu = new LedDeviceSedu(output, rate);
deviceSedu->open();
device = deviceSedu;
} }
else if (type == "test") else if (type == "test")
{ {
const std::string output = deviceConfig["output"].asString(); const std::string output = deviceConfig["output"].asString();
device = new LedDeviceTest(output); device = new LedDeviceTest(output);
} }
else if (type == "ws2812b")
{
LedDeviceWs2812b * deviceWs2812b = new LedDeviceWs2812b();
deviceWs2812b->open();
device = deviceWs2812b;
}
else else
{ {
std::cout << "Unable to create device " << type << std::endl; std::cout << "Unable to create device " << type << std::endl;

View File

@ -0,0 +1,130 @@
// STL includes
#include <cerrno>
#include <cstring>
// QT includes
#include <QFile>
// Local LedDevice includes
#include "LedDevicePiBlaster.h"
LedDevicePiBlaster::LedDevicePiBlaster(const std::string & deviceName, const std::string & channelAssignment) :
_deviceName(deviceName),
_channelAssignment(channelAssignment),
_fid(nullptr)
{
// empty
}
LedDevicePiBlaster::~LedDevicePiBlaster()
{
// Close the device (if it is opened)
if (_fid != nullptr)
{
fclose(_fid);
_fid = nullptr;
}
}
int LedDevicePiBlaster::open(bool report)
{
if (_fid != nullptr)
{
// The file pointer is already open
if (report)
{
std::cerr << "Attempt to open allready opened device (" << _deviceName << ")" << std::endl;
}
return -1;
}
if (!QFile::exists(_deviceName.c_str()))
{
if (report)
{
std::cerr << "The device(" << _deviceName << ") does not yet exist, can not connect (yet)." << std::endl;
}
return -1;
}
_fid = fopen(_deviceName.c_str(), "w");
if (_fid == nullptr)
{
if (report)
{
std::cerr << "Failed to open device (" << _deviceName << "). Error message: " << strerror(errno) << std::endl;
}
return -1;
}
std::cout << "Connect to device(" << _deviceName << ")" << std::endl;
return 0;
}
//Channel number GPIO number Pin in P1 header
// 0 4 P1-7
// 1 17 P1-11
// 2 18 P1-12
// 3 21 P1-13
// 4 22 P1-15
// 5 23 P1-16
// 6 24 P1-18
// 7 25 P1-22
int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
{
// Attempt to open if not yet opened
if (_fid == nullptr && open(false) < 0)
{
return -1;
}
unsigned colorIdx = 0;
for (unsigned iChannel=0; iChannel<8; ++iChannel)
{
double pwmDutyCycle = 0.0;
switch (_channelAssignment[iChannel])
{
case 'r':
pwmDutyCycle = ledValues[colorIdx].red / 255.0;
++colorIdx;
break;
case 'g':
pwmDutyCycle = ledValues[colorIdx].green / 255.0;
++colorIdx;
break;
case 'b':
pwmDutyCycle = ledValues[colorIdx].blue / 255.0;
++colorIdx;
break;
default:
continue;
}
fprintf(_fid, "%i=%f\n", iChannel, pwmDutyCycle);
fflush(_fid);
}
return 0;
}
int LedDevicePiBlaster::switchOff()
{
// Attempt to open if not yet opened
if (_fid == nullptr && open(false) < 0)
{
return -1;
}
for (unsigned iChannel=0; iChannel<8; ++iChannel)
{
if (_channelAssignment[iChannel] != ' ')
{
fprintf(_fid, "%i=%f\n", iChannel, 0.0);
fflush(_fid);
}
}
return 0;
}

View File

@ -0,0 +1,59 @@
#pragma once
// STL includes
#include <cstdio>
// Hyperion-Leddevice includes
#include <leddevice/LedDevice.h>
class LedDevicePiBlaster : public LedDevice
{
public:
///
/// Constructs the PiBlaster device which writes to the indicated device and for the assigned
/// channels
/// @param deviceName The name of the output device
/// @param channelAssignment The RGB-Channel assignment (8 characters long)
///
LedDevicePiBlaster(const std::string & deviceName, const std::string & channelAssignment);
virtual ~LedDevicePiBlaster();
///
/// Attempts to open the piblaster-device. This will only succeed if the device is not yet open
/// and the device is available.
///
/// @param report If true errors are writen to the standard error else silent
/// @return Zero on succes else negative
///
int open(bool report = true);
///
/// Writes the colors to the PiBlaster device
///
/// @param ledValues The color value for each led
///
/// @return Zero on success else negative
///
int write(const std::vector<ColorRgb> &ledValues);
///
/// Switches off the leds
///
/// @return Zero on success else negative
///
int switchOff();
private:
/// The name of the output device (very likely '/dev/pi-blaster')
const std::string _deviceName;
/// String with eight characters with the rgb-channel assignment per pwm-channel
/// ('r' = red, 'g' = green, 'b' = blue, ' ' = empty)
const std::string _channelAssignment;
/// File-Pointer to the PiBlaster device
FILE * _fid;
};

View File

@ -1,90 +1,96 @@
// Linux includes
#include <unistd.h>
// Local Hyperion-Leddevice includes // Local Hyperion-Leddevice includes
#include "LedDeviceWs2812b.h" #include "LedDeviceWs2812b.h"
LedDeviceWs2812b::LedDeviceWs2812b() : LedDeviceWs2812b::LedDeviceWs2812b() :
LedRs232Device("/dev/ttyAMA0", 4000000) LedRs232Device("/dev/ttyAMA0", 2000000)
{ {
fillTable(); // empty
} }
int LedDeviceWs2812b::write(const std::vector<ColorRgb> & ledValues) int LedDeviceWs2812b::write(const std::vector<ColorRgb> & ledValues)
{ {
// Ensure the size of the led-buffer // Ensure the size of the led-buffer
if (_ledBuffer.size() != ledValues.size()*3) if (_ledBuffer.size() != ledValues.size()*8)
{ {
_ledBuffer.resize(ledValues.size()*3); _ledBuffer.resize(ledValues.size()*8, ~0x24);
} }
// Translate the channel of each color to a signal // Translate the channel of each color to a signal
auto bufIt = _ledBuffer.begin(); uint8_t * signal_ptr = _ledBuffer.data();
for (const ColorRgb& color : ledValues) for (const ColorRgb & color : ledValues)
{ {
*bufIt++ = _byte2signalTable[color.red]; signal_ptr = color2signal(color, signal_ptr);
*bufIt++ = _byte2signalTable[color.green];
*bufIt++ = _byte2signalTable[color.blue];
} }
return writeBytes(_ledBuffer.size()*sizeof(ByteSignal), reinterpret_cast<uint8_t *>(_ledBuffer.data())); const int result = writeBytes(_ledBuffer.size(), _ledBuffer.data());
// Official latch time is 50us (lets give it 50us more)
usleep(100);
return result;
}
uint8_t * LedDeviceWs2812b::color2signal(const ColorRgb & color, uint8_t * signal)
{
*signal = bits2Signal(color.red & 0x80, color.red & 0x40, color.red & 0x20);
++signal;
*signal = bits2Signal(color.red & 0x10, color.red & 0x08, color.red & 0x04);
++signal;
*signal = bits2Signal(color.red & 0x02, color.green & 0x01, color.green & 0x80);
++signal;
*signal = bits2Signal(color.green & 0x40, color.green & 0x20, color.green & 0x10);
++signal;
*signal = bits2Signal(color.green & 0x08, color.green & 0x04, color.green & 0x02);
++signal;
*signal = bits2Signal(color.green & 0x01, color.blue & 0x80, color.blue & 0x40);
++signal;
*signal = bits2Signal(color.blue & 0x20, color.blue & 0x10, color.blue & 0x08);
++signal;
*signal = bits2Signal(color.blue & 0x04, color.blue & 0x02, color.blue & 0x01);
++signal;
return signal;
} }
int LedDeviceWs2812b::switchOff() int LedDeviceWs2812b::switchOff()
{ {
// Set all bytes in the signal buffer to zero // Set all bytes in the signal buffer to zero
for (ByteSignal & signal : _ledBuffer) for (uint8_t & signal : _ledBuffer)
{ {
signal = _byte2signalTable[0]; signal = ~0x24;
} }
return writeBytes(_ledBuffer.size()*sizeof(ByteSignal), reinterpret_cast<uint8_t *>(_ledBuffer.data())); return writeBytes(_ledBuffer.size(), _ledBuffer.data());
} }
void LedDeviceWs2812b::fillTable() uint8_t LedDeviceWs2812b::bits2Signal(const bool bit_1, const bool bit_2, const bool bit_3) const
{
_byte2signalTable.clear();
for (int byte=0; byte<256; ++byte)
{
const ByteSignal signal = byte2Signal(uint8_t(byte));
_byte2signalTable.push_back(signal);
}
}
LedDeviceWs2812b::ByteSignal LedDeviceWs2812b::byte2Signal(const uint8_t byte) const
{
ByteSignal result;
result.bit_12 = bits2Signal(byte & 0x80, byte & 0x40);
result.bit_34 = bits2Signal(byte & 0x20, byte & 0x10);
result.bit_56 = bits2Signal(byte & 0x08, byte & 0x04);
result.bit_78 = bits2Signal(byte & 0x02, byte & 0x01);
return result;
}
uint8_t LedDeviceWs2812b::bits2Signal(const bool bit1, const bool bit2) const
{ {
// See https://github.com/tvdzwan/hyperion/wiki/Ws2812b for the explanation of the given // See https://github.com/tvdzwan/hyperion/wiki/Ws2812b for the explanation of the given
// translations // translations
if (bit1)
// Bit index(default):1 2 3
// | | |
// default value (1) 00 100 10 (0)
//
// Reversed value (1) 01 001 00 (0)
// | | |
// Bit index (rev): 3 2 1
uint8_t result = 0x24;
if(bit_1)
{ {
if (bit2) result |= 0x01;
{
return 0x8C;
}
else
{
return 0xCC;
}
} }
else if (bit_2)
{ {
if (bit2) result |= 0x08;
{ }
return 0x8E; if (bit_3)
} {
else result |= 0x40;
{
return 0xCE;
}
} }
return 0x00; return ~result;
} }

View File

@ -34,43 +34,27 @@ public:
private: private:
/// ///
/// Structure holding the four output-bytes corresponding to a single input byte /// Translate a color to the signal bits. The resulting bits are written to the given memory.
/// ///
struct ByteSignal /// @param color The color to translate
{ /// @param signal The pointer at the beginning of the signal to write
uint8_t bit_12; /// @return The pointer at the end of the written signal
uint8_t bit_34; ///
uint8_t bit_56; uint8_t * color2signal(const ColorRgb & color, uint8_t * signal);
uint8_t bit_78;
};
/// Translation table from single input-byte to output-bytes
std::vector<ByteSignal> _byte2signalTable;
/// ///
/// Fills the translation table (_byte2signalTable) /// Translates three bits to a single byte
///
void fillTable();
///
/// Computes the output bytes that belong to a given input-byte (no table lookup)
///
/// @param byte The input byte
/// @return The four bytes (ByteSignal) for the output signal
///
ByteSignal byte2Signal(const uint8_t byte) const;
///
/// Translates two bits to a single byte
/// ///
/// @param bit1 The value of the first bit (1=true, zero=false) /// @param bit1 The value of the first bit (1=true, zero=false)
/// @param bit1 The value of the ssecond bit (1=true, zero=false) /// @param bit2 The value of the second bit (1=true, zero=false)
/// @param bit3 The value of the third bit (1=true, zero=false)
/// ///
/// @return The output-byte for the given two bit /// @return The output-byte for the given two bit
/// ///
uint8_t bits2Signal(const bool bit1, const bool bit2) const; uint8_t bits2Signal(const bool bit1, const bool bit2, const bool bit3) const;
/// ///
/// The output buffer for writing bytes to the output /// The output buffer for writing bytes to the output
/// ///
std::vector<ByteSignal> _ledBuffer; std::vector<uint8_t> _ledBuffer;
}; };

View File

@ -57,6 +57,7 @@ int LedRs232Device::writeBytes(const unsigned size, const uint8_t * data)
try try
{ {
_rs232Port.flushOutput();
_rs232Port.write(data, size); _rs232Port.write(data, size);
_rs232Port.flush(); _rs232Port.flush();
} }

View File

@ -1 +0,0 @@
/.metadata

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="output" path="classes"/>
</classpath>

View File

@ -1,3 +0,0 @@
/.settings
/classes
/hyerpcon.dat

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ConfigTool</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -1,32 +0,0 @@
<?xml version="1.0"?>
<project default="main" basedir=".">
<tstamp/>
<property name="version" value="1.0" />
<property name="deploy.dir" value="${basedir}/../../../deploy" />
<target name="main" depends="make_deploy_dir, build" description="Build HyperCon, the Hyperion configuration file builder" />
<target name="build" depends="make_deploy_dir" description="Create HyperCon.jar">
<jar destfile="HyperCon.jar">
<manifest>
<attribute name="Main-Class" value="org.hyperion.hypercon.Main" />
<attribute name="Specification-Title" value="HyperCon"/>
<attribute name="Specification-Version" value="${version}"/>
<attribute name="Specification-Vendor" value="Hyperion Team"/>
<attribute name="Implementation-Title" value="org.hyperion"/>
<attribute name="Implementation-Version" value="${version} - ${TODAY}"/>
<attribute name="Implementation-Vendor" value="Hyperion Team"/>
</manifest>
<fileset dir="classes" />
</jar>
<move file="HyperCon.jar" todir="${deploy.dir}" />
</target>
<target name="make_deploy_dir">
<mkdir dir="${deploy.dir}" />
</target>
</project>

View File

@ -1,288 +0,0 @@
package org.hyperion.hypercon;
import java.awt.Color;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.Properties;
import java.util.Vector;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* Class for supporting the serialisation and deserialisation of HyperCon settings.
*/
public class ConfigurationFile {
/** Temporary storage of the HyperCon configuration */
private final Properties mProps = new Properties();
/**
* Loads the configuration of HyperCon from the given filename into this {@link ConfigurationFile}
*
* @param pFilename The absolute filename containing the configuration
*/
public void load(String pFilename) {
mProps.clear();
// try (InputStream in = new InflaterInputStream(new FileInputStream(pFilename))){
try (InputStream in = new GZIPInputStream(new FileInputStream(pFilename))){
// try (InputStream in = new FileInputStream(pFilename)) {
mProps.load(in);
} catch (Throwable t) {
// TODO Auto-generated catch block
t.printStackTrace();
}
}
/**
* Saves the configuration of this {@link ConfigurationFile} to the given filename
*
* @param pFilename The absolute filename to which to save the HyperCon configuration
*/
public void save(String pFilename) {
// try (OutputStream out = new DeflaterOutputStream(new FileOutputStream(pFilename))) {
try (OutputStream out = new GZIPOutputStream(new FileOutputStream(pFilename))) {
// try (OutputStream out = (new FileOutputStream(pFilename))) {
mProps.store(out, "Pesistent settings file for HyperCon");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Stores the given object to the local properties object
*
* @param pObj The object to store
*/
public void store(Object pObj) {
store(pObj, pObj.getClass().getSimpleName(), "");
}
/**
* Stores the given object to the local properties object (with given preamble and postamble)
*
* @param pObj The object to store
* @param preamble The preamble prepended to the key of the object members
* @param postamble The postamble appended to the key of the object members
*/
public void store(Object pObj, String preamble, String postamble) {
String className = pObj.getClass().getSimpleName();
// Retrieve the member variables
Field[] fields = pObj.getClass().getDeclaredFields();
// Iterate each variable
for (Field field : fields) {
if (!Modifier.isPublic(field.getModifiers())) {
System.out.println("Unable to synchronise non-public field(" + field.getName() + ") in configuration structure(" + className + ")");
continue;
}
String key = preamble + "." + field.getName() + postamble;
try {
Object value = field.get(pObj);
if (field.getType() == boolean.class) {
mProps.setProperty(key, Boolean.toString((boolean) value));
} else if (field.getType() == int.class) {
mProps.setProperty(key, Integer.toString((int) value));
} else if (field.getType() == double.class) {
mProps.setProperty(key, Double.toString((double) value));
} else if (field.getType() == String.class) {
mProps.setProperty(key, (String)value);
} else if (field.getType() == Color.class) {
Color color = (Color)value;
mProps.setProperty(key, String.format("[%d; %d; %d]", color.getRed(), color.getGreen(), color.getBlue()));
} else if (value.getClass().isEnum()) {
mProps.setProperty(key, ((Enum<?>)value).name());
} else if (value instanceof Vector) {
@SuppressWarnings("unchecked")
Vector<Object> v = (Vector<Object>) value;
for (int i=0; i<v.size(); ++i) {
store(v.get(i), key + "[" + i + "]", "");
}
} else if (field.getType() == Object.class) {
if (value instanceof Boolean) {
mProps.setProperty(key, Boolean.toString((boolean) value));
} if (value instanceof Integer) {
mProps.setProperty(key, Integer.toString((int) value));
} else if (value instanceof Double) {
mProps.setProperty(key, Double.toString((double) value));
} else if (value instanceof Color) {
Color color = (Color)value;
mProps.setProperty(key, String.format("[%d; %d; %d]", color.getRed(), color.getGreen(), color.getBlue()));
} else if (value instanceof String) {
mProps.setProperty(key, '"' + (String)value + '"');
}
} else {
System.out.println("Might not be able to load: " + key + " = " + value.toString());
mProps.setProperty(key, value.toString());
}
} catch (Throwable t) {}
}
}
/**
* Restores the object from the local properties object
*
* @param pObj The object to restore
*/
public void restore(Object pObj) {
restore(pObj, mProps);
}
/**
* Restores the object from the given object object
*
* @param pObj The object to restore
* @param pProps The properties containing values for the members of obj
*/
public void restore(Object pObj, Properties pProps) {
String className = pObj.getClass().getSimpleName();
restore(pObj, pProps, className + ".");
}
/**
* Restores the object from the given settings object, using the given preamble
*
* @param pObj The object to restore
* @param pProps The properties containing values for the members of obj
* @param pPreamble The preamble to use
*/
@SuppressWarnings("unchecked")
public void restore(Object pObj, Properties pProps, String pPreamble) {
// Retrieve the member variables
Field[] fields = pObj.getClass().getDeclaredFields();
// Iterate each variable
for (Field field : fields) {
if (field.getType().equals(Vector.class)) {
// Obtain the Vector
Vector<Object> vector;
try {
vector = (Vector<Object>)field.get(pObj);
} catch (Throwable t) {
t.printStackTrace();
break;
}
// Clear existing elements from the vector
vector.clear();
// Iterate through the properties to find the indices of the vector
int i=0;
while (true) {
String curIndexKey = pPreamble + field.getName() + "[" + i + "]";
Properties elemProps = new Properties();
// Find all the elements for the current vector index
for (Object keyObj : pProps.keySet()) {
String keyStr = (String)keyObj;
if (keyStr.startsWith(curIndexKey)) {
// Remove the name and dot
elemProps.put(keyStr.substring(curIndexKey.length()+1), pProps.get(keyStr));
}
}
if (elemProps.isEmpty()) {
// Found no more elements for the vector
break;
}
// Construct new instance of vectors generic type
ParameterizedType vectorElementType = (ParameterizedType) field.getGenericType();
Class<?> vectorElementClass = (Class<?>) vectorElementType.getActualTypeArguments()[0];
// Find the constructor with no arguments and create a new instance
Object newElement = null;
try {
newElement = vectorElementClass.getConstructor().newInstance();
} catch (Throwable t) {
System.err.println("Failed to find empty default constructor for " + vectorElementClass.getName());
break;
}
if (newElement == null) {
System.err.println("Failed to construct instance for " + vectorElementClass.getName());
break;
}
// Restore the instance members from the collected properties
restore(newElement, elemProps, "");
// Add the instance to the vector
vector.addElement(newElement);
++i;
}
continue;
}
String key = pPreamble + field.getName();
String value = pProps.getProperty(key);
if (value == null) {
System.out.println("Persistent settings does not contain value for " + key);
continue;
}
try {
if (field.getType() == boolean.class) {
field.set(pObj, Boolean.parseBoolean(value));
} else if (field.getType() == int.class) {
field.set(pObj, Integer.parseInt(value));
} else if (field.getType() == double.class) {
field.set(pObj, Double.parseDouble(value));
} else if (field.getType() == Color.class) {
String[] channelValues = value.substring(1, value.length()-1).split(";");
field.set(pObj, new Color(Integer.parseInt(channelValues[0].trim()), Integer.parseInt(channelValues[1].trim()), Integer.parseInt(channelValues[2].trim())));
} else if (field.getType() == String.class) {
field.set(pObj, value);
} else if (field.getType().isEnum()) {
Method valMet = field.getType().getMethod("valueOf", String.class);
Object enumVal = valMet.invoke(null, value);
field.set(pObj, enumVal);
} else if (field.getType() == Object.class) {
// We can not infer from the type of the field, let's try the actual stored value
if (value.isEmpty()) {
// We will never known ...
} else if (value.startsWith("[") && value.endsWith("]")) {
String[] channelValues = value.substring(1, value.length()-1).split(";");
field.set(pObj, new Color(Integer.parseInt(channelValues[0].trim()), Integer.parseInt(channelValues[1].trim()), Integer.parseInt(channelValues[2].trim())));
} else if (value.startsWith("\"") && value.endsWith("\"")) {
field.set(pObj, value.substring(1, value.length()-1));
} else {
try {
int i = Integer.parseInt(value);
field.set(pObj, i);
} catch (Throwable t1) {
try {
double d = Double.parseDouble(value);
field.set(pObj, d);
} catch (Throwable t2) {
try {
boolean bool = Boolean.parseBoolean(value);
field.set(pObj, bool);
} catch (Throwable t3) {
}
}
}
}
}
} catch (Throwable t) {
System.out.println("Failed to parse value(" + value + ") for " + key);
t.printStackTrace();
}
}
}
/**
* Returns a String representation of this ConfigurationFile, which is the {@link #toString()}
* of the underlying {@link Properties}
*
* @return The String representation of this ConfigurationFile
*/
@Override
public String toString() {
return mProps.toString();
}
}

View File

@ -1,6 +0,0 @@
package org.hyperion.hypercon;
public class HyperConConfig {
public boolean loadDefaultEffect = true;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -1,226 +0,0 @@
package org.hyperion.hypercon;
public class JsonStringBuffer {
private final StringBuffer mStrBuf = new StringBuffer();
private final int mStartIndentLevel;
private int mIndentLevel = 0;
/** Flag indicating that the parts written are 'commented-out' */
private boolean mComment = false;
public JsonStringBuffer() {
this(0);
mStrBuf.append("{\n");
++mIndentLevel;
}
public JsonStringBuffer(int pIndentLevel) {
mStartIndentLevel = pIndentLevel;
mIndentLevel = pIndentLevel;
}
public void newLine() {
mStrBuf.append('\n');
}
public void finish() {
for (int i=0; i<mIndentLevel; ++i) {
mStrBuf.append('\t');
}
mStrBuf.append("\"end-of-json\" : \"end-of-json\"\n");
--mIndentLevel;
if (mIndentLevel != mStartIndentLevel) {
System.err.println("Json write closed in incorrect state!");
}
for (int i=0; i<mIndentLevel; ++i) {
mStrBuf.append('\t');
}
mStrBuf.append("}\n");
}
public void writeComment(String pComment) {
String[] commentLines = pComment.split("\\r?\\n");
for (String commentLine : commentLines) {
for (int i=0; i<mIndentLevel; ++i) {
mStrBuf.append('\t');
}
mStrBuf.append("/// ").append(commentLine).append('\n');
}
}
public void toggleComment(boolean b) {
mComment = b;
}
private void startLine() {
if (mComment) mStrBuf.append("// ");
for (int i=0; i<mIndentLevel; ++i) {
mStrBuf.append('\t');
}
}
public void startObject(String pKey) {
if (!pKey.isEmpty()) {
startLine();
mStrBuf.append('"').append(pKey).append('"').append(" : \n");
}
startLine();
mStrBuf.append("{\n");
++mIndentLevel;
}
public void stopObject(boolean endOfSection) {
--mIndentLevel;
startLine();
if (endOfSection) {
mStrBuf.append("}\n");
} else {
mStrBuf.append("},\n");
}
}
public void stopObject() {
--mIndentLevel;
startLine();
mStrBuf.append("},\n");
}
public void startArray(String pKey) {
startLine();
mStrBuf.append('"').append(pKey).append('"').append(" : \n");
startLine();
mStrBuf.append("[\n");
++mIndentLevel;
}
public void stopArray(boolean lastValue) {
--mIndentLevel;
startLine();
if (lastValue) {
mStrBuf.append("]\n");
} else {
mStrBuf.append("],\n");
}
}
public void addRawValue(String pKey, String pValue, boolean lastValue) {
startLine();
mStrBuf.append('"').append(pKey).append('"').append(" : ").append(pValue);
if (lastValue) {
mStrBuf.append("\n");
} else {
mStrBuf.append(",\n");
}
}
public void addValue(String pKey, String pValue, boolean lastValue) {
startLine();
mStrBuf.append('"').append(pKey).append('"').append(" : ").append('"').append(pValue).append('"');
if (lastValue) {
mStrBuf.append("\n");
} else {
mStrBuf.append(",\n");
}
}
public void addValue(String pKey, double pValue, boolean lastValue) {
startLine();
mStrBuf.append('"').append(pKey).append('"').append(" : ").append(pValue);
if (lastValue) {
mStrBuf.append("\n");
} else {
mStrBuf.append(",\n");
}
}
public void addValue(String pKey, int pValue, boolean lastValue) {
startLine();
mStrBuf.append('"').append(pKey).append('"').append(" : ").append(pValue);
if (lastValue) {
mStrBuf.append("\n");
} else {
mStrBuf.append(",\n");
}
}
public void addValue(String pKey, boolean pValue, boolean lastValue) {
startLine();
mStrBuf.append('"').append(pKey).append('"').append(" : ").append(pValue);
if (lastValue) {
mStrBuf.append("\n");
} else {
mStrBuf.append(",\n");
}
}
/**
* Adds an array element to an opened array.
*
* @param pValue The value of the element
* @param pLastValue Indicates that it is the last element in the array
*/
public void addArrayElement(String pValue, boolean pLastValue) {
startLine();
mStrBuf.append('"').append(pValue).append('"');
if (pLastValue) {
mStrBuf.append("\n");
} else {
mStrBuf.append(",\n");
}
}
@Override
public String toString() {
return mStrBuf.toString();
}
public static void main(String[] pArgs) {
JsonStringBuffer jsonBuf = new JsonStringBuffer();
String comment = "Device configuration contains the following fields: \n" +
"* 'name' : The user friendly name of the device (only used for display purposes) \n" +
"* 'type' : The type of the device or leds (known types for now are 'ws2801', 'lpd6803', 'sedu', 'test' and 'none') \n" +
"* 'output' : The output specification depends on selected device \n" +
" - 'ws2801' this is the device (eg '/dev/spidev0.0 or /dev/ttyS0') \n" +
" - 'test' this is the file used to write test output (eg '/home/pi/hyperion.out') \n" +
"* 'rate' : The baudrate of the output to the device \n" +
"* 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.). \n";
jsonBuf.writeComment(comment);
jsonBuf.startObject("device");
jsonBuf.addValue("name", "MyPi", false);
jsonBuf.addValue("type", "ws2801", false);
jsonBuf.addValue("output", "/dev/spidev0.0", false);
jsonBuf.addValue("rate", 1000000, false);
jsonBuf.addValue("colorOrder", "rgb", true);
jsonBuf.stopObject();
jsonBuf.toggleComment(true);
jsonBuf.startObject("device");
jsonBuf.addValue("name", "MyPi", false);
jsonBuf.addValue("type", "ws2801", false);
jsonBuf.addValue("output", "/dev/spidev0.0", false);
jsonBuf.addValue("rate", 1000000, false);
jsonBuf.addValue("colorOrder", "rgb", true);
jsonBuf.stopObject();
jsonBuf.toggleComment(false);
jsonBuf.finish();
System.out.println(jsonBuf.toString());
}
}

View File

@ -1,274 +0,0 @@
package org.hyperion.hypercon;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Collections;
import java.util.Comparator;
import java.util.Vector;
import org.hyperion.hypercon.spec.BorderSide;
import org.hyperion.hypercon.spec.ImageProcessConfig;
import org.hyperion.hypercon.spec.Led;
import org.hyperion.hypercon.spec.LedFrameConstruction;
/**
* The LedFrameFactory translates user specifications (number of leds, etc) to actual led
* specifications (location of led, depth and width of integration, etc)
*/
public class LedFrameFactory {
/**
* Convenience method for increasing the led counter (it might actually decrease if the frame is
* counter clockwise)
*
* @param frameSpec The specification of the led-frame
* @param pLedCounter The current led counter
* @return The counter/index of the next led
*/
private static int increase(LedFrameConstruction frameSpec, int pLedCounter) {
if (frameSpec.clockwiseDirection) {
return (pLedCounter+1)%frameSpec.getLedCount();
} else {
if (pLedCounter == 0) {
return frameSpec.getLedCount() - 1;
}
return pLedCounter -1;
}
}
/**
* Translate a 'frame' and picture integration specification to per-led specification
*
* @param frameSpec The specification of the led frame
* @param processConfig The picture integration specification
*
* @return The per-led specification
*/
public static Vector<Led> construct(LedFrameConstruction frameSpec, ImageProcessConfig processConfig) {
Vector<Led> mLeds = new Vector<>();
int totalLedCount = frameSpec.getLedCount();
if (totalLedCount <= 0) {
return mLeds;
}
// Determine the led-number of the top-left led
int iLed = (totalLedCount - frameSpec.firstLedOffset)%totalLedCount;
if (iLed < 0) {
iLed += totalLedCount;
}
// Construct the top-left led (if top-left is enabled)
if (frameSpec.topCorners) {
mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 0.0, processConfig.getOverlapFraction(), BorderSide.top_left));
iLed = increase(frameSpec, iLed);
}
// Construct all leds along the top of the screen (if any)
if (frameSpec.topLedCnt > 0) {
// Determine the led-spacing
int ledCnt = frameSpec.topLedCnt;
double ledSpacing = (double)1.0/(ledCnt);
for (int iTop=0; iTop<ledCnt; ++iTop) {
// Compute the location of this led
double led_x = ledSpacing/2.0 + iTop * ledSpacing;
double led_y = 0;
// Construct and add the single led specification to the list of leds
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.top));
iLed = increase(frameSpec, iLed);
}
}
// Construct the top-right led (if top-right is enabled)
if (frameSpec.topCorners) {
mLeds.add(createLed(frameSpec, processConfig, iLed, 1.0, 0.0, processConfig.getOverlapFraction(), BorderSide.top_right));
iLed = increase(frameSpec, iLed);
}
// Construct all leds along the right of the screen (if any)
if (frameSpec.rightLedCnt > 0) {
// Determine the led-spacing
int ledCnt = frameSpec.rightLedCnt;
double ledSpacing = 1.0/ledCnt;
for (int iRight=0; iRight<ledCnt; ++iRight) {
// Compute the location of this led
double led_x = 1.0;
double led_y = ledSpacing/2.0 + iRight * ledSpacing;
// Construct and add the single led specification to the list of leds
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.right));
iLed = increase(frameSpec, iLed);
}
}
// Construct the bottom-right led (if bottom-right is enabled)
if (frameSpec.bottomCorners) {
mLeds.add(createLed(frameSpec, processConfig, iLed, 1.0, 1.0, processConfig.getOverlapFraction(), BorderSide.bottom_right));
iLed = increase(frameSpec, iLed);
}
// Construct all leds along the bottom of the screen (if any)
if (frameSpec.bottomLedCnt > 0) {
// Determine the led-spacing (based on top-leds [=bottom leds + gap size])
int ledCnt = frameSpec.topLedCnt;
double ledSpacing = (double)1.0/ledCnt;
for (int iBottom=(ledCnt-1); iBottom>=0; --iBottom) {
// Special case for the bottom-gap
if (iBottom > (frameSpec.bottomLedCnt-1)/2 && iBottom < ledCnt - frameSpec.bottomLedCnt/2) {
continue;
}
// Compute the location of this led
double led_x = ledSpacing/2.0 + iBottom * ledSpacing;
double led_y = 1.0;
// Construct and add the single led specification to the list of leds
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.bottom));
iLed = increase(frameSpec, iLed);
}
}
// Construct the bottom-left led (if bottom-left is enabled)
if (frameSpec.bottomCorners) {
mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 1.0, processConfig.getOverlapFraction(), BorderSide.bottom_left));
iLed = increase(frameSpec, iLed);
}
// Construct all leds along the left of the screen (if any)
if (frameSpec.leftLedCnt > 0) {
// Determine the led-spacing
int ledCnt = frameSpec.leftLedCnt;
double ledSpacing = (double)1.0/ledCnt;
for (int iRight=(ledCnt-1); iRight>=0; --iRight) {
// Compute the location of this led
double led_x = 0.0;
double led_y = ledSpacing/2.0 + iRight * ledSpacing;
// Construct and add the single led specification to the list of leds
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.left));
iLed = increase(frameSpec, iLed);
}
}
Collections.sort(mLeds, new Comparator<Led>() {
@Override
public int compare(Led o1, Led o2) {
return Integer.compare(o1.mLedSeqNr, o2.mLedSeqNr);
}
});
return mLeds;
}
/**
* Constructs the specification of a single led
*
* @param pFrameSpec The overall led-frame specification
* @param pProcessSpec The overall image-processing specification
* @param seqNr The number of the led
* @param x_frac The x location of the led in fractional range [0.0; 1.0]
* @param y_frac The y location of the led in fractional range [0.0; 1.0]
* @param overlap_frac The fractional overlap of the led integration with its neighbor
* @param pBorderSide The side on which the led is located
*
* @return The image integration specifications of the single led
*/
private static Led createLed(LedFrameConstruction pFrameSpec, ImageProcessConfig pProcessSpec, int seqNr, double x_frac, double y_frac, double overlap_frac, BorderSide pBorderSide) {
Led led = new Led();
led.mLedSeqNr = seqNr;
led.mLocation = new Point2D.Double(x_frac, y_frac);
led.mSide = pBorderSide;
double xFrac = pProcessSpec.getVerticalGap() + (1.0-2*pProcessSpec.getVerticalGap()) * x_frac;
double yFrac = pProcessSpec.getHorizontalGap() + (1.0-2*pProcessSpec.getHorizontalGap()) * y_frac;
double widthFrac = ((1.0-2*pProcessSpec.getVerticalGap())/pFrameSpec.topLedCnt * (1.0 + overlap_frac))/2.0;
double heightFrac = ((1.0-2*pProcessSpec.getHorizontalGap())/pFrameSpec.leftLedCnt * (1.0 + overlap_frac))/2.0;
double horizontalDepth = Math.min(1.0 - pProcessSpec.getHorizontalGap(), pProcessSpec.getHorizontalDepth());
double verticalDepth = Math.min(1.0 - pProcessSpec.getVerticalGap(), pProcessSpec.getVerticalDepth());
switch (pBorderSide) {
case top_left: {
led.mImageRectangle = new Rectangle2D.Double(
pProcessSpec.getVerticalGap(),
pProcessSpec.getHorizontalGap(),
verticalDepth,
horizontalDepth);
break;
}
case top_right: {
led.mImageRectangle = new Rectangle2D.Double(
1.0-pProcessSpec.getVerticalGap()-verticalDepth,
pProcessSpec.getHorizontalGap(),
verticalDepth,
horizontalDepth);
break;
}
case bottom_left: {
led.mImageRectangle = new Rectangle2D.Double(
pProcessSpec.getVerticalGap(),
1.0-pProcessSpec.getHorizontalGap()-horizontalDepth,
verticalDepth,
horizontalDepth);
break;
}
case bottom_right: {
led.mImageRectangle = new Rectangle2D.Double(
1.0-pProcessSpec.getVerticalGap()-verticalDepth,
1.0-pProcessSpec.getHorizontalGap()-horizontalDepth,
verticalDepth,
horizontalDepth);
break;
}
case top:{
double intXmin_frac = Math.max(0.0, xFrac-widthFrac);
double intXmax_frac = Math.min(xFrac+widthFrac, 1.0);
led.mImageRectangle = new Rectangle2D.Double(
intXmin_frac,
pProcessSpec.getHorizontalGap(),
intXmax_frac-intXmin_frac,
horizontalDepth);
break;
}
case bottom:
{
double intXmin_frac = Math.max(0.0, xFrac-widthFrac);
double intXmax_frac = Math.min(xFrac+widthFrac, 1.0);
led.mImageRectangle = new Rectangle2D.Double(
intXmin_frac,
1.0-pProcessSpec.getHorizontalGap()-horizontalDepth,
intXmax_frac-intXmin_frac,
horizontalDepth);
break;
}
case left: {
double intYmin_frac = Math.max(0.0, yFrac-heightFrac);
double intYmax_frac = Math.min(yFrac+heightFrac, 1.0);
led.mImageRectangle = new Rectangle2D.Double(
pProcessSpec.getVerticalGap(),
intYmin_frac,
verticalDepth,
intYmax_frac-intYmin_frac);
break;
}
case right:
double intYmin_frac = Math.max(0.0, yFrac-heightFrac);
double intYmax_frac = Math.min(yFrac+heightFrac, 1.0);
led.mImageRectangle = new Rectangle2D.Double(
1.0-pProcessSpec.getVerticalGap()-verticalDepth,
intYmin_frac,
verticalDepth,
intYmax_frac-intYmin_frac);
break;
}
return led;
}
}

View File

@ -1,105 +0,0 @@
package org.hyperion.hypercon;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Locale;
import java.util.Vector;
import org.hyperion.hypercon.spec.ColorConfig;
import org.hyperion.hypercon.spec.DeviceConfig;
import org.hyperion.hypercon.spec.ImageProcessConfig;
import org.hyperion.hypercon.spec.Led;
import org.hyperion.hypercon.spec.LedFrameConstruction;
import org.hyperion.hypercon.spec.MiscConfig;
/**
* The full configuration of Hyperion with sub-items for device, color and miscelanuous items.
*/
public class LedString {
/** The configuration of the output device */
public final DeviceConfig mDeviceConfig = new DeviceConfig();
/** THe configuration of the 'physical' led frame */
public final LedFrameConstruction mLedFrameConfig = new LedFrameConstruction();
/** The configuration of the image processing */
public final ImageProcessConfig mProcessConfig = new ImageProcessConfig();
/** The color adjustment configuration */
public final ColorConfig mColorConfig = new ColorConfig();
/** The miscellaneous configuration (bootsequence, blackborder detector, etc) */
public final MiscConfig mMiscConfig = new MiscConfig();
/** The translation of the led frame construction and image processing to individual led configuration */
public Vector<Led> leds;
/**
* Writes the configuration to the given file
*
* @param mFilename The absolute filename
*
* @throws IOException If unable to write the given file
*/
public void saveConfigFile(String mFilename) throws IOException {
try (FileWriter fw = new FileWriter(mFilename)) {
fw.write("// Automatically generated configuration file for 'Hyperion daemon'\n");
fw.write("// Generated by: HyperCon (The Hyperion deamon configuration file builder\n");
fw.write("\n");
fw.write("{\n");
String deviceJson = mDeviceConfig.toJsonString();
fw.write(deviceJson + ",\n\n");
String colorJson = mColorConfig.toJsonString();
fw.write(colorJson + ",\n\n");
JsonStringBuffer jsonBuf = new JsonStringBuffer(1);
ledsAppendTo(jsonBuf);
jsonBuf.newLine();
mProcessConfig.appendTo(jsonBuf);
jsonBuf.newLine();
mMiscConfig.appendTo(jsonBuf);
jsonBuf.newLine();
jsonBuf.addValue("endOfJson", "endOfJson", true);
fw.write(jsonBuf.toString());
fw.write("}\n");
} catch (IOException e) {
throw e;
}
}
void ledsAppendTo(JsonStringBuffer pJsonBuf) {
String ledComment =
" The configuration for each individual led. This contains the specification of the area \n" +
" averaged of an input image for each led to determine its color. Each item in the list \n" +
" contains the following fields:\n" +
" * index: The index of the led. This determines its location in the string of leds; zero \n" +
" being the first led.\n" +
" * hscan: The fractional part of the image along the horizontal used for the averaging \n" +
" (minimum and maximum inclusive)\n" +
" * vscan: The fractional part of the image along the vertical used for the averaging \n" +
" (minimum and maximum inclusive)\n";
pJsonBuf.writeComment(ledComment);
pJsonBuf.startArray("leds");
for (Led led : leds)
{
pJsonBuf.startObject("");
pJsonBuf.addValue("index", led.mLedSeqNr, false);
pJsonBuf.addRawValue("hscan", String.format(Locale.ENGLISH, "{ %1$cminimum%1$c : %2$.4f, %1$cmaximum%1$c : %3$.4f }", '"', led.mImageRectangle.getMinX(), led.mImageRectangle.getMaxX()), false);
pJsonBuf.addRawValue("vscan", String.format(Locale.ENGLISH, "{ %1$cminimum%1$c : %2$.4f, %1$cmaximum%1$c : %3$.4f }", '"', led.mImageRectangle.getMinY(), led.mImageRectangle.getMaxY()), true);
pJsonBuf.stopObject(led.equals(leds.get(leds.size()-1)));
}
pJsonBuf.stopArray(false);
}
}

View File

@ -1,87 +0,0 @@
package org.hyperion.hypercon;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.UIManager;
import org.hyperion.hypercon.gui.ConfigPanel;
import org.hyperion.hypercon.spec.TransformConfig;
/**
* (static) Main-class for starting HyperCon (the Hyperion configuration file builder) as a standard
* JAVA application (contains the entry-point).
*/
public class Main {
public static final String configFilename = "hypercon.dat";
/** Some application settings (for easy/dirty access) */
public static final HyperConConfig HyperConConfig = new HyperConConfig();
/**
* Entry point to start HyperCon
*
* @param pArgs HyperCon does not have command line arguments
*/
public static void main(String[] pArgs) {
final String versionStr = Main.class.getPackage().getImplementationVersion();
final LedString ledString = new LedString();
try {
// Configure swing to use the system default look and feel
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {}
// Create a frame for the configuration panel
JFrame frame = new JFrame();
String title = "Hyperion configuration Tool" + ((versionStr != null && !versionStr.isEmpty())? (" (" + versionStr + ")") : "");
frame.setTitle(title);
frame.setSize(1300, 700);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setIconImage(new ImageIcon(Main.class.getResource("HyperConIcon_64.png")).getImage());
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
ConfigurationFile configFile = new ConfigurationFile();
configFile.store(Main.HyperConConfig);
configFile.store(ledString.mDeviceConfig);
configFile.store(ledString.mLedFrameConfig);
configFile.store(ledString.mProcessConfig);
configFile.store(ledString.mColorConfig);
configFile.store(ledString.mMiscConfig);
configFile.save(configFilename);
} catch (Throwable t) {
System.err.println("Failed to save " + configFilename);
}
}
});
if (new File(configFilename).exists()) {
try {
ConfigurationFile configFile = new ConfigurationFile();
configFile.load(configFilename);
configFile.restore(Main.HyperConConfig);
configFile.restore(ledString.mDeviceConfig);
configFile.restore(ledString.mLedFrameConfig);
configFile.restore(ledString.mProcessConfig);
configFile.restore(ledString.mColorConfig);
configFile.restore(ledString.mMiscConfig);
} catch (Throwable t) {
System.err.println("Failed to load " + configFilename);
}
if (ledString.mColorConfig.mTransforms.isEmpty()) {
ledString.mColorConfig.mTransforms.add(new TransformConfig());
}
}
// Add the HyperCon configuration panel
frame.setContentPane(new ConfigPanel(ledString));
// Show the frame
frame.setVisible(true);
}
}

View File

@ -1,141 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.Transient;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.hyperion.hypercon.spec.ColorConfig;
import org.hyperion.hypercon.spec.ColorSmoothingType;
public class ColorSmoothingPanel extends JPanel {
private final ColorConfig mColorConfig;
private JCheckBox mEnabledCheck;
private JLabel mTypeLabel;
private JComboBox<ColorSmoothingType> mTypeCombo;
private JLabel mTimeLabel;
private JSpinner mTimeSpinner;
private JLabel mUpdateFrequencyLabel;
private JSpinner mUpdateFrequencySpinner;
public ColorSmoothingPanel(final ColorConfig pColorConfig) {
super();
mColorConfig = pColorConfig;
initialise();
}
@Override
@Transient
public Dimension getMaximumSize() {
Dimension maxSize = super.getMaximumSize();
Dimension prefSize = super.getPreferredSize();
return new Dimension(maxSize.width, prefSize.height);
}
private void initialise() {
setBorder(BorderFactory.createTitledBorder("Smoothing"));
mEnabledCheck = new JCheckBox("Enabled");
mEnabledCheck.setSelected(mColorConfig.mSmoothingEnabled);
mEnabledCheck.addActionListener(mActionListener);
add(mEnabledCheck);
mTypeLabel = new JLabel("Type: ");
add(mTypeLabel);
mTypeCombo = new JComboBox<>(ColorSmoothingType.values());
mTypeCombo.setSelectedItem(mColorConfig.mSmoothingType);
mTypeCombo.addActionListener(mActionListener);
add(mTypeCombo);
mTimeLabel = new JLabel("Time [ms]: ");
add(mTimeLabel);
mTimeSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mSmoothingTime_ms, 1, 600, 100));
mTimeSpinner.addChangeListener(mChangeListener);
add(mTimeSpinner);
mUpdateFrequencyLabel = new JLabel("Update Freq. [Hz]: ");
add(mUpdateFrequencyLabel);
mUpdateFrequencySpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mSmoothingUpdateFrequency_Hz, 1, 100, 1));
mUpdateFrequencySpinner.addChangeListener(mChangeListener);
add(mUpdateFrequencySpinner);
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mEnabledCheck)
.addComponent(mTypeLabel)
.addComponent(mTimeLabel)
.addComponent(mUpdateFrequencyLabel)
)
.addGroup(layout.createParallelGroup()
.addComponent(mEnabledCheck)
.addComponent(mTypeCombo)
.addComponent(mTimeSpinner)
.addComponent(mUpdateFrequencySpinner)
));
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(mEnabledCheck)
.addGroup(layout.createParallelGroup()
.addComponent(mTypeLabel)
.addComponent(mTypeCombo)
)
.addGroup(layout.createParallelGroup()
.addComponent(mTimeLabel)
.addComponent(mTimeSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mUpdateFrequencyLabel)
.addComponent(mUpdateFrequencySpinner)
));
toggleEnabled(mColorConfig.mSmoothingEnabled);
}
private void toggleEnabled(boolean pEnabled) {
mTypeLabel.setEnabled(pEnabled);
mTypeCombo.setEnabled(pEnabled);
mTimeLabel.setEnabled(pEnabled);
mTimeSpinner.setEnabled(pEnabled);
mUpdateFrequencyLabel.setEnabled(pEnabled);
mUpdateFrequencySpinner.setEnabled(pEnabled);
}
private final ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mColorConfig.mSmoothingEnabled = mEnabledCheck.isSelected();
mColorConfig.mSmoothingType = (ColorSmoothingType)mTypeCombo.getSelectedItem();
toggleEnabled(mColorConfig.mSmoothingEnabled);
}
};
private final ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mColorConfig.mSmoothingTime_ms = (Integer)mTimeSpinner.getValue();
mColorConfig.mSmoothingUpdateFrequency_Hz = (Double)mUpdateFrequencySpinner.getValue();
}
};
}

View File

@ -1,277 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.beans.Transient;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.hyperion.hypercon.spec.TransformConfig;
/**
* Configuration panel for the ColorConfig.
*
* NB This has not been integrated in the GUI jet!
*/
public class ColorTransformPanel extends JPanel {
private final Dimension maxDim = new Dimension(1024, 20);
private final TransformConfig mColorConfig;
private JPanel mIndexPanel;
private JLabel mIndexLabel;
private JTextField mIndexField;
private JPanel mRgbTransformPanel;
private JLabel mThresholdLabel;
private JLabel mGammaLabel;
private JLabel mBlacklevelLabel;
private JLabel mWhitelevelLabel;
private JLabel mRedTransformLabel;
private JSpinner mRedThresholdSpinner;
private JSpinner mRedGammaSpinner;
private JSpinner mRedBlacklevelSpinner;
private JSpinner mRedWhitelevelSpinner;
private JLabel mGreenTransformLabel;
private JSpinner mGreenThresholdSpinner;
private JSpinner mGreenGammaSpinner;
private JSpinner mGreenBlacklevelSpinner;
private JSpinner mGreenWhitelevelSpinner;
private JLabel mBlueTransformLabel;
private JSpinner mBlueThresholdSpinner;
private JSpinner mBlueGammaSpinner;
private JSpinner mBlueBlacklevelSpinner;
private JSpinner mBlueWhitelevelSpinner;
private JPanel mHsvTransformPanel;
private JLabel mSaturationAdjustLabel;
private JSpinner mSaturationAdjustSpinner;
private JLabel mValueAdjustLabel;
private JSpinner mValueAdjustSpinner;
public ColorTransformPanel(TransformConfig pTransformConfig) {
super();
mColorConfig = pTransformConfig;
initialise();
}
@Override
@Transient
public Dimension getMaximumSize() {
Dimension maxSize = super.getMaximumSize();
Dimension prefSize = super.getPreferredSize();
return new Dimension(maxSize.width, prefSize.height);
}
private void initialise() {
setBorder(BorderFactory.createTitledBorder("Transform [" + mColorConfig.mId + "]"));
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(getIndexPanel());
add(Box.createVerticalStrut(10));
add(getRgbPanel());
add(Box.createVerticalStrut(10));
add(getHsvPanel());
add(Box.createVerticalGlue());
}
private JPanel getIndexPanel() {
if (mIndexPanel == null) {
mIndexPanel = new JPanel();
mIndexPanel.setMaximumSize(new Dimension(1024, 25));
mIndexPanel.setLayout(new BorderLayout(10,10));
mIndexLabel = new JLabel("Indices:");
mIndexPanel.add(mIndexLabel, BorderLayout.WEST);
mIndexField = new JTextField(mColorConfig.mLedIndexString);
mIndexField.setToolTipText("Comma seperated indices or index ranges (eg '1-10, 13, 14, 17-19'); Special case '*', which means all leds");
mIndexField.getDocument().addDocumentListener(mDocumentListener);
mIndexPanel.add(mIndexField, BorderLayout.CENTER);
}
return mIndexPanel;
}
private JPanel getRgbPanel() {
if (mRgbTransformPanel == null) {
mRgbTransformPanel = new JPanel();
GridLayout layout = new GridLayout(0, 5);
// GroupLayout layout = new GroupLayout(mRgbTransformPanel);
mRgbTransformPanel.setLayout(layout);
mRgbTransformPanel.add(Box.createHorizontalBox());
mThresholdLabel = new JLabel("Thres.");
mRgbTransformPanel.add(mThresholdLabel);
mGammaLabel = new JLabel("Gamma");
mRgbTransformPanel.add(mGammaLabel);
mBlacklevelLabel = new JLabel("Blacklvl");
mRgbTransformPanel.add(mBlacklevelLabel);
mWhitelevelLabel = new JLabel("Whitelvl");
mRgbTransformPanel.add(mWhitelevelLabel);
mRedTransformLabel = new JLabel("RED");
mRgbTransformPanel.add(mRedTransformLabel);
mRedThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedThreshold, 0.0, 1.0, 0.1));
mRedThresholdSpinner.setMaximumSize(maxDim);
mRedThresholdSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mRedThresholdSpinner);
mRedGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedGamma, 0.0, 100.0, 0.1));
mRedGammaSpinner.setMaximumSize(maxDim);
mRedGammaSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mRedGammaSpinner);
mRedBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedBlacklevel, 0.0, 1.0, 0.1));
mRedBlacklevelSpinner.setMaximumSize(maxDim);
mRedBlacklevelSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mRedBlacklevelSpinner);
mRedWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mRedWhitelevel, 0.0, 1.0, 0.1));
mRedWhitelevelSpinner.setMaximumSize(maxDim);
mRedWhitelevelSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mRedWhitelevelSpinner);
mGreenTransformLabel = new JLabel("GREEN");
mRgbTransformPanel.add(mGreenTransformLabel);
mGreenThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenThreshold, 0.0, 1.0, 0.1));
mGreenThresholdSpinner.setMaximumSize(maxDim);
mGreenThresholdSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mGreenThresholdSpinner);
mGreenGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenGamma, 0.0, 100.0, 0.1));
mGreenGammaSpinner.setMaximumSize(maxDim);
mGreenGammaSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mGreenGammaSpinner);
mGreenBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenBlacklevel, 0.0, 1.0, 0.1));
mGreenBlacklevelSpinner.setMaximumSize(maxDim);
mGreenBlacklevelSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mGreenBlacklevelSpinner);
mGreenWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mGreenWhitelevel, 0.0, 1.0, 0.1));
mGreenWhitelevelSpinner.setMaximumSize(maxDim);
mGreenWhitelevelSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mGreenWhitelevelSpinner);
mBlueTransformLabel = new JLabel("BLUE");
mRgbTransformPanel.add(mBlueTransformLabel);
mBlueThresholdSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueThreshold, 0.0, 1.0, 0.1));
mBlueThresholdSpinner.setMaximumSize(maxDim);
mBlueThresholdSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mBlueThresholdSpinner);
mBlueGammaSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueGamma, 0.0, 100.0, 0.1));
mBlueGammaSpinner.setMaximumSize(maxDim);
mBlueGammaSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mBlueGammaSpinner);
mBlueBlacklevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueBlacklevel, 0.0, 1.0, 0.1));
mBlueBlacklevelSpinner.setMaximumSize(maxDim);
mBlueBlacklevelSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mBlueBlacklevelSpinner);
mBlueWhitelevelSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mBlueWhitelevel, 0.0, 1.0, 0.1));
mBlueWhitelevelSpinner.setMaximumSize(maxDim);
mBlueWhitelevelSpinner.addChangeListener(mChangeListener);
mRgbTransformPanel.add(mBlueWhitelevelSpinner);
}
return mRgbTransformPanel;
}
private JPanel getHsvPanel() {
if (mHsvTransformPanel == null) {
mHsvTransformPanel = new JPanel();
GroupLayout layout = new GroupLayout(mHsvTransformPanel);
mHsvTransformPanel.setLayout(layout);
mSaturationAdjustLabel = new JLabel("HSV Saturation gain");
mHsvTransformPanel.add(mSaturationAdjustLabel);
mSaturationAdjustSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mSaturationGain, 0.0, 1024.0, 0.01));
mSaturationAdjustSpinner.setMaximumSize(maxDim);
mSaturationAdjustSpinner.addChangeListener(mChangeListener);
mHsvTransformPanel.add(mSaturationAdjustSpinner);
mValueAdjustLabel = new JLabel("HSV Value gain");
mHsvTransformPanel.add(mValueAdjustLabel);
mValueAdjustSpinner = new JSpinner(new SpinnerNumberModel(mColorConfig.mValueGain, 0.0, 1024.0, 0.01));
mValueAdjustSpinner.setMaximumSize(maxDim);
mValueAdjustSpinner.addChangeListener(mChangeListener);
mHsvTransformPanel.add(mValueAdjustSpinner);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mSaturationAdjustLabel)
.addComponent(mValueAdjustLabel)
)
.addGroup(layout.createParallelGroup()
.addComponent(mSaturationAdjustSpinner)
.addComponent(mValueAdjustSpinner)
)
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mSaturationAdjustLabel)
.addComponent(mSaturationAdjustSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mValueAdjustLabel)
.addComponent(mValueAdjustSpinner)
)
);
}
return mHsvTransformPanel;
}
private final ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mColorConfig.mRedThreshold = (Double)mRedThresholdSpinner.getValue();
mColorConfig.mRedGamma = (Double)mRedGammaSpinner.getValue();
mColorConfig.mRedBlacklevel = (Double)mRedBlacklevelSpinner.getValue();
mColorConfig.mRedWhitelevel = (Double)mRedWhitelevelSpinner.getValue();
mColorConfig.mGreenThreshold = (Double)mGreenThresholdSpinner.getValue();
mColorConfig.mGreenGamma = (Double)mGreenGammaSpinner.getValue();
mColorConfig.mGreenBlacklevel = (Double)mGreenBlacklevelSpinner.getValue();
mColorConfig.mGreenWhitelevel = (Double)mGreenWhitelevelSpinner.getValue();
mColorConfig.mBlueThreshold = (Double)mBlueThresholdSpinner.getValue();
mColorConfig.mBlueGamma = (Double)mBlueGammaSpinner.getValue();
mColorConfig.mBlueBlacklevel = (Double)mBlueBlacklevelSpinner.getValue();
mColorConfig.mBlueWhitelevel = (Double)mBlueWhitelevelSpinner.getValue();
mColorConfig.mSaturationGain = (Double)mSaturationAdjustSpinner.getValue();
mColorConfig.mValueGain = (Double)mValueAdjustSpinner.getValue();
}
};
private final DocumentListener mDocumentListener = new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
mColorConfig.mLedIndexString = mIndexField.getText();
}
@Override
public void insertUpdate(DocumentEvent e) {
mColorConfig.mLedIndexString = mIndexField.getText();
}
@Override
public void changedUpdate(DocumentEvent e) {
mColorConfig.mLedIndexString = mIndexField.getText();
}
};
}

View File

@ -1,130 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import org.hyperion.hypercon.spec.ColorConfig;
import org.hyperion.hypercon.spec.TransformConfig;
public class ColorsPanel extends JPanel {
private final ColorConfig mColorConfig;
private final DefaultComboBoxModel<TransformConfig> mTransformsModel;
private JPanel mControlPanel;
private JComboBox<TransformConfig> mTransformCombo;
private JButton mAddTransformButton;
private JButton mDelTransformButton;
private JPanel mTransformPanel;
private final Map<TransformConfig, ColorTransformPanel> mTransformPanels = new HashMap<>();
public ColorsPanel(ColorConfig pColorConfig) {
super();
mColorConfig = pColorConfig;
mTransformsModel = new DefaultComboBoxModel<TransformConfig>(mColorConfig.mTransforms);
initialise();
}
private void initialise() {
setLayout(new BorderLayout(10,10));
setBorder(BorderFactory.createTitledBorder("Colors"));
add(getControlPanel(), BorderLayout.NORTH);
mTransformPanel = new JPanel();
mTransformPanel.setLayout(new BorderLayout());
add(mTransformPanel, BorderLayout.CENTER);
for (TransformConfig config : mColorConfig.mTransforms) {
mTransformPanels.put(config, new ColorTransformPanel(config));
}
ColorTransformPanel currentPanel = mTransformPanels.get(mColorConfig.mTransforms.get(0));
mTransformPanel.add(currentPanel, BorderLayout.CENTER);
}
private JPanel getControlPanel() {
if (mControlPanel == null) {
mControlPanel = new JPanel();
mControlPanel.setLayout(new BoxLayout(mControlPanel, BoxLayout.LINE_AXIS));
mTransformCombo = new JComboBox<>(mTransformsModel);
mTransformCombo.addActionListener(mComboListener);
mControlPanel.add(mTransformCombo);
mAddTransformButton = new JButton(mAddAction);
mControlPanel.add(mAddTransformButton);
mDelTransformButton = new JButton(mDelAction);
mDelTransformButton.setEnabled(mTransformCombo.getItemCount() > 1);
mControlPanel.add(mDelTransformButton);
}
return mControlPanel;
}
private final Action mAddAction = new AbstractAction("Add") {
@Override
public void actionPerformed(ActionEvent e) {
String newId = JOptionPane.showInputDialog("Give an identifier for the new color-transform:");
if (newId == null || newId.isEmpty()) {
// No proper value given
return;
}
TransformConfig config = new TransformConfig();
config.mId = newId;
ColorTransformPanel panel = new ColorTransformPanel(config);
mTransformPanels.put(config, panel);
mTransformsModel.addElement(config);
mTransformsModel.setSelectedItem(config);
mDelTransformButton.setEnabled(true);
}
};
private final Action mDelAction = new AbstractAction("Del") {
@Override
public void actionPerformed(ActionEvent e) {
TransformConfig config = (TransformConfig) mTransformCombo.getSelectedItem();
mTransformPanels.remove(config);
mTransformsModel.removeElement(config);
mDelTransformButton.setEnabled(mTransformCombo.getItemCount() > 1);
}
};
private final ActionListener mComboListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TransformConfig selConfig = (TransformConfig) mTransformsModel.getSelectedItem();
if (selConfig == null) {
// Something went wrong here, there should always be a selection!
return;
}
ColorTransformPanel panel = mTransformPanels.get(selConfig);
mTransformPanel.removeAll();
mTransformPanel.add(panel, BorderLayout.CENTER);
mTransformPanel.revalidate();
mTransformPanel.repaint();
}
};
}

View File

@ -1,194 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import org.hyperion.hypercon.ConfigurationFile;
import org.hyperion.hypercon.LedFrameFactory;
import org.hyperion.hypercon.LedString;
import org.hyperion.hypercon.Main;
/**
* The main-config panel of HyperCon. Includes the configuration and the panels to edit and
* write-out the configuration. This can be placed on JFrame, JDialog or JApplet as required.
*/
public class ConfigPanel extends JPanel {
/** The LED configuration information*/
private final LedString ledString;
/** Action for write the Hyperion deamon configuration file */
private final Action mSaveConfigAction = new AbstractAction("Create Hyperion Configuration") {
JFileChooser fileChooser = new JFileChooser();
{
fileChooser.setSelectedFile(new File("hyperion.config.json"));
}
@Override
public void actionPerformed(ActionEvent e) {
if (fileChooser.showSaveDialog(ConfigPanel.this) != JFileChooser.APPROVE_OPTION) {
return;
}
try {
ledString.saveConfigFile(fileChooser.getSelectedFile().getAbsolutePath());
ConfigurationFile configFile = new ConfigurationFile();
configFile.store(ledString.mDeviceConfig);
configFile.store(ledString.mLedFrameConfig);
configFile.store(ledString.mProcessConfig);
configFile.store(ledString.mColorConfig);
configFile.store(ledString.mMiscConfig);
configFile.save(Main.configFilename);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
};
/** The panel for containing the example 'Hyperion TV' */
private JPanel mTvPanel;
/** The simulated 'Hyperion TV' */
private LedSimulationComponent mHyperionTv;
private JTabbedPane mSpecificationTabs = null;
/** The left (WEST) side panel containing the diferent configuration panels */
private JPanel mHardwarePanel = null;
private JPanel mProcessPanel = null;
private JPanel mExternalPanel = null;
/** The button connected to mSaveConfigAction */
private JButton mSaveConfigButton;
/**
* Constructs the configuration panel with a default initialised led-frame and configuration
*/
public ConfigPanel(final LedString pLedString) {
super();
ledString = pLedString;
initialise();
// Compute the individual leds for the current configuration
ledString.leds = LedFrameFactory.construct(ledString.mLedFrameConfig, ledString.mProcessConfig);
mHyperionTv.setLeds(ledString.leds);
// Add Observer to update the individual leds if the configuration changes
final Observer observer = new Observer() {
@Override
public void update(Observable o, Object arg) {
ledString.leds = LedFrameFactory.construct(ledString.mLedFrameConfig, ledString.mProcessConfig);
mHyperionTv.setLeds(ledString.leds);
mHyperionTv.repaint();
}
};
ledString.mLedFrameConfig.addObserver(observer);
ledString.mProcessConfig.addObserver(observer);
}
/**
* Initialises the config-panel
*/
private void initialise() {
setLayout(new BorderLayout());
add(getTvPanel(), BorderLayout.CENTER);
add(getWestPanel(), BorderLayout.WEST);
}
private JPanel getWestPanel() {
JPanel mWestPanel = new JPanel();
mWestPanel.setLayout(new BorderLayout());
mWestPanel.add(getSpecificationTabs(), BorderLayout.CENTER);
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
mSaveConfigButton = new JButton(mSaveConfigAction);
panel.add(mSaveConfigButton, BorderLayout.SOUTH);
mWestPanel.add(panel, BorderLayout.SOUTH);
return mWestPanel;
}
private JTabbedPane getSpecificationTabs() {
if (mSpecificationTabs == null) {
mSpecificationTabs = new JTabbedPane();
mSpecificationTabs.addTab("Hardware", getHardwarePanel());
mSpecificationTabs.addTab("Process", getProcessPanel());
mSpecificationTabs.addTab("External", getExternalPanel());
}
return mSpecificationTabs;
}
/**
* Created, if not exists, and returns the panel holding the simulated 'Hyperion TV'
*
* @return The Tv panel
*/
private JPanel getTvPanel() {
if (mTvPanel == null) {
mTvPanel = new JPanel();
mTvPanel.setLayout(new BorderLayout());
mHyperionTv = new LedSimulationComponent(ledString.leds);
mTvPanel.add(mHyperionTv, BorderLayout.CENTER);
}
return mTvPanel;
}
private JPanel getHardwarePanel() {
if (mHardwarePanel == null) {
mHardwarePanel = new JPanel();
mHardwarePanel.setLayout(new BoxLayout(mHardwarePanel, BoxLayout.Y_AXIS));
mHardwarePanel.add(new DevicePanel(ledString.mDeviceConfig));
mHardwarePanel.add(new LedFramePanel(ledString.mLedFrameConfig));
mHardwarePanel.add(new ImageProcessPanel(ledString.mProcessConfig));
mHardwarePanel.add(Box.createVerticalGlue());
}
return mHardwarePanel;
}
private JPanel getProcessPanel() {
if (mProcessPanel == null) {
mProcessPanel = new JPanel();
mProcessPanel.setLayout(new BoxLayout(mProcessPanel, BoxLayout.Y_AXIS));
mProcessPanel.add(new FrameGrabberPanel(ledString.mMiscConfig));
mProcessPanel.add(new ColorSmoothingPanel(ledString.mColorConfig));
mProcessPanel.add(new ColorsPanel(ledString.mColorConfig));
mProcessPanel.add(Box.createVerticalGlue());
}
return mProcessPanel;
}
private JPanel getExternalPanel() {
if (mExternalPanel == null) {
mExternalPanel = new JPanel();
mExternalPanel.setLayout(new BoxLayout(mExternalPanel, BoxLayout.Y_AXIS));
mExternalPanel.add(new XbmcPanel(ledString.mMiscConfig));
mExternalPanel.add(new InterfacePanel(ledString.mMiscConfig));
mExternalPanel.add(new EffectEnginePanel(ledString.mMiscConfig));
mExternalPanel.add(Box.createVerticalGlue());
}
return mExternalPanel;
}
}

View File

@ -1,117 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.Transient;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.hyperion.hypercon.gui.device.DeviceTypePanel;
import org.hyperion.hypercon.spec.ColorByteOrder;
import org.hyperion.hypercon.spec.DeviceConfig;
import org.hyperion.hypercon.spec.DeviceType;
public class DevicePanel extends JPanel {
public static final String[] KnownOutputs = {"/dev/spidev0.0", "/dev/spidev0.1", "/dev/ttyS0", "/dev/ttyUSB0", "/dev/ttyprintk", "/home/pi/test.out", "/dev/null"};
private final DeviceConfig mDeviceConfig;
private JLabel mTypeLabel;
private JComboBox<DeviceType> mTypeCombo;
private JPanel mDevicePanel;
private JLabel mRgbLabel;
private JComboBox<ColorByteOrder> mRgbCombo;
public DevicePanel(DeviceConfig pDeviceConfig) {
super();
mDeviceConfig = pDeviceConfig;
initialise();
}
@Override
@Transient
public Dimension getMaximumSize() {
Dimension maxSize = super.getMaximumSize();
Dimension prefSize = super.getPreferredSize();
return new Dimension(maxSize.width, prefSize.height);
}
private void initialise() {
setBorder(BorderFactory.createTitledBorder("Device"));
mTypeLabel = new JLabel("Type: ");
mTypeLabel.setMinimumSize(new Dimension(80, 10));
add(mTypeLabel);
mTypeCombo = new JComboBox<>(DeviceType.values());
mTypeCombo.setSelectedItem(mDeviceConfig.mType);
mTypeCombo.addActionListener(mActionListener);
add(mTypeCombo);
mDevicePanel = new JPanel();
mDevicePanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
mDevicePanel.setLayout(new BorderLayout());
DeviceTypePanel typePanel = mDeviceConfig.mType.getConfigPanel(mDeviceConfig);
if (typePanel != null) {
mDevicePanel.add(typePanel, BorderLayout.CENTER);
}
add(mDevicePanel);
mRgbLabel = new JLabel("RGB Byte Order: ");
mRgbLabel.setMinimumSize(new Dimension(80, 10));
add(mRgbLabel);
mRgbCombo = new JComboBox<>(ColorByteOrder.values());
mRgbCombo.setSelectedItem(mDeviceConfig.mColorByteOrder);
mRgbCombo.addActionListener(mActionListener);
add(mRgbCombo);
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup()
.addGroup(layout.createSequentialGroup()
.addComponent(mTypeLabel)
.addComponent(mTypeCombo))
.addComponent(mDevicePanel)
.addGroup(layout.createSequentialGroup()
.addComponent(mRgbLabel)
.addComponent(mRgbCombo)));
layout.setVerticalGroup(layout.createParallelGroup()
.addGroup(layout.createSequentialGroup()
.addComponent(mTypeLabel)
.addComponent(mDevicePanel)
.addComponent(mRgbLabel))
.addGroup(layout.createSequentialGroup()
.addComponent(mTypeCombo)
.addComponent(mDevicePanel)
.addComponent(mRgbCombo)));
}
private final ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mDeviceConfig.mType = (DeviceType)mTypeCombo.getSelectedItem();
mDeviceConfig.mColorByteOrder = (ColorByteOrder)mRgbCombo.getSelectedItem();
mDevicePanel.removeAll();
DeviceTypePanel typePanel = mDeviceConfig.mType.getConfigPanel(mDeviceConfig);
if (typePanel != null) {
mDevicePanel.add(typePanel, BorderLayout.CENTER);
}
revalidate();
}
};
}

View File

@ -1,175 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.hyperion.hypercon.spec.MiscConfig;
/**
* THe EffectEnginePanel contains the components for configuring the parameters of the Effect Engine
*/
public class EffectEnginePanel extends JPanel {
/** The MISC config contains the effect engine settings */
private final MiscConfig mMiscConfig;
private JLabel mPathLabel;
private JTextField mPathField;
private JPanel mBootSequencePanel;
private JCheckBox mBootSequenceCheck;
private JLabel mBootSequenceLabel;
private JTextField mBootSequenceField;
private JLabel mBootSequenceLengthLabel;
private JSpinner mBootSequenceLengthSpinner;
public EffectEnginePanel(final MiscConfig pMiscConfig) {
super();
mMiscConfig = pMiscConfig;
initialise();
}
private void initialise() {
setBorder(BorderFactory.createTitledBorder("Effect Engine"));
mPathLabel = new JLabel("Directory: ");
mPathLabel.setMinimumSize(new Dimension(80, 10));
add(mPathLabel);
mPathField = new JTextField();
mPathField.setMaximumSize(new Dimension(1024, 20));
mPathField.setText(mMiscConfig.mEffectEnginePath);
mPathField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
mMiscConfig.mEffectEnginePath = mPathField.getText();
}
@Override
public void insertUpdate(DocumentEvent e) {
mMiscConfig.mEffectEnginePath = mPathField.getText();
}
@Override
public void changedUpdate(DocumentEvent e) {
mMiscConfig.mEffectEnginePath = mPathField.getText();
}
});
add(mPathField);
add(getBootSequencePanel());
GroupLayout layout = new GroupLayout(this);
setLayout(layout);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mPathLabel)
.addComponent(mPathField))
.addComponent(getBootSequencePanel()));
layout.setHorizontalGroup(layout.createParallelGroup()
.addGroup(layout.createSequentialGroup()
.addComponent(mPathLabel)
.addComponent(mPathField))
.addComponent(getBootSequencePanel()));
}
private JPanel getBootSequencePanel() {
if (mBootSequencePanel == null) {
mBootSequencePanel = new JPanel();
mBootSequencePanel.setBorder(BorderFactory.createTitledBorder("Bootsequence"));
mBootSequenceCheck = new JCheckBox("Enabled");
mBootSequenceCheck.setSelected(mMiscConfig.mBootSequenceEnabled);
mBootSequenceCheck.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mMiscConfig.mBootSequenceEnabled = mBootSequenceCheck.isSelected();
mBootSequenceLabel.setEnabled(mMiscConfig.mBootSequenceEnabled);
mBootSequenceField.setEnabled(mMiscConfig.mBootSequenceEnabled);
}
});
mBootSequencePanel.add(mBootSequenceCheck);
mBootSequenceLabel = new JLabel("Type:");
mBootSequenceLabel.setMinimumSize(new Dimension(75, 10));
mBootSequenceLabel.setEnabled(mMiscConfig.mBootSequenceEnabled);
mBootSequencePanel.add(mBootSequenceLabel);
mBootSequenceField = new JTextField();
mBootSequenceField.setMaximumSize(new Dimension(1024, 20));
mBootSequenceField.setText(mMiscConfig.mBootSequenceEffect);
mBootSequenceField.setEnabled(mMiscConfig.mBootSequenceEnabled);
mBootSequenceField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
mMiscConfig.mBootSequenceEffect = mBootSequenceField.getText();
}
@Override
public void insertUpdate(DocumentEvent e) {
mMiscConfig.mBootSequenceEffect = mBootSequenceField.getText();
}
@Override
public void changedUpdate(DocumentEvent e) {
mMiscConfig.mBootSequenceEffect = mBootSequenceField.getText();
}
});
mBootSequencePanel.add(mBootSequenceField);
mBootSequenceLengthLabel = new JLabel("Length[ms]: ");
mBootSequenceLengthLabel.setMinimumSize(new Dimension(75, 10));
mBootSequenceLengthLabel.setEnabled(mMiscConfig.mBootSequenceEnabled);
mBootSequencePanel.add(mBootSequenceLengthLabel);
mBootSequenceLengthSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mBootSequenceLength_ms, 100, 1500000, 500));
mBootSequenceLengthSpinner.setMaximumSize(new Dimension(1024, 20));
mBootSequenceLengthSpinner.setEnabled(mMiscConfig.mBootSequenceEnabled);
mBootSequenceLengthSpinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mMiscConfig.mBootSequenceLength_ms = (Integer)mBootSequenceLengthSpinner.getValue();
}
});
mBootSequencePanel.add(mBootSequenceLengthSpinner);
GroupLayout layout = new GroupLayout(mBootSequencePanel);
mBootSequencePanel.setLayout(layout);
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(mBootSequenceCheck)
.addGroup(layout.createParallelGroup()
.addComponent(mBootSequenceLabel)
.addComponent(mBootSequenceField))
.addGroup(layout.createParallelGroup()
.addComponent(mBootSequenceLengthLabel)
.addComponent(mBootSequenceLengthSpinner))
);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mBootSequenceCheck)
.addComponent(mBootSequenceLabel)
.addComponent(mBootSequenceLengthLabel))
.addGroup(layout.createParallelGroup()
.addComponent(mBootSequenceCheck)
.addComponent(mBootSequenceField)
.addComponent(mBootSequenceLengthSpinner)));
}
return mBootSequencePanel;
}
}

View File

@ -1,137 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.Transient;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.hyperion.hypercon.spec.MiscConfig;
public class FrameGrabberPanel extends JPanel {
private final MiscConfig mMiscConfig;
private JCheckBox mFrameGrabberCheck;
private JLabel mWidthLabel;
private JSpinner mWidthSpinner;
private JLabel mHeightLabel;
private JSpinner mHeightSpinner;
private JLabel mIntervalLabel;
private JSpinner mIntervalSpinner;
public FrameGrabberPanel(final MiscConfig pMiscConfig) {
super();
mMiscConfig = pMiscConfig;
initialise();
}
@Override
@Transient
public Dimension getMaximumSize() {
Dimension maxSize = super.getMaximumSize();
Dimension prefSize = super.getPreferredSize();
return new Dimension(maxSize.width, prefSize.height);
}
private void initialise() {
setBorder(BorderFactory.createTitledBorder("Frame Grabber"));
mFrameGrabberCheck = new JCheckBox("Enabled");
mFrameGrabberCheck.setSelected(mMiscConfig.mFrameGrabberEnabled);
mFrameGrabberCheck.addActionListener(mActionListener);
add(mFrameGrabberCheck);
mWidthLabel = new JLabel("Width: ");
add(mWidthLabel);
mWidthSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mFrameGrabberWidth, 16, 1024, 8));
mWidthSpinner.addChangeListener(mChangeListener);
add(mWidthSpinner);
mHeightLabel = new JLabel("Heigth: ");
add(mHeightLabel);
mHeightSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mFrameGrabberHeight, 16, 1024, 8));
mHeightSpinner.addChangeListener(mChangeListener);
add(mHeightSpinner);
mIntervalLabel = new JLabel("Interval [ms]:");
add(mIntervalLabel);
mIntervalSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mFrameGrabberInterval_ms, 10, 60000, 10));
mIntervalSpinner.addChangeListener(mChangeListener);
add(mIntervalSpinner);
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mFrameGrabberCheck)
.addComponent(mWidthLabel)
.addComponent(mHeightLabel)
.addComponent(mIntervalLabel)
)
.addGroup(layout.createParallelGroup()
.addComponent(mFrameGrabberCheck)
.addComponent(mWidthSpinner)
.addComponent(mHeightSpinner)
.addComponent(mIntervalSpinner)
));
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(mFrameGrabberCheck)
.addGroup(layout.createParallelGroup()
.addComponent(mWidthLabel)
.addComponent(mWidthSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mHeightLabel)
.addComponent(mHeightSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mIntervalLabel)
.addComponent(mIntervalSpinner)
));
toggleEnabled(mMiscConfig.mFrameGrabberEnabled);
}
private void toggleEnabled(boolean pEnabled) {
mWidthLabel.setEnabled(pEnabled);
mWidthSpinner.setEnabled(pEnabled);
mHeightLabel.setEnabled(pEnabled);
mHeightSpinner.setEnabled(pEnabled);
mIntervalLabel.setEnabled(pEnabled);
mIntervalSpinner.setEnabled(pEnabled);
}
private final ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mMiscConfig.mFrameGrabberEnabled = mFrameGrabberCheck.isSelected();
toggleEnabled(mMiscConfig.mFrameGrabberEnabled);
}
};
private final ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mMiscConfig.mFrameGrabberWidth = (Integer)mWidthSpinner.getValue();
mMiscConfig.mFrameGrabberHeight = (Integer)mHeightSpinner.getValue();
mMiscConfig.mFrameGrabberInterval_ms = (Integer)mIntervalSpinner.getValue();
}
};
}

View File

@ -1,27 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JComponent;
public class ImageComponent extends JComponent {
private Image mImage;
public ImageComponent() {
super();
}
public void setImage(Image pImage) {
mImage = pImage;
}
@Override
public void paint(Graphics g) {
if (mImage == null) {
return;
}
g.drawImage(mImage, 0, 0, getWidth(), getHeight(), null);
}
}

View File

@ -1,177 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.Transient;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.hyperion.hypercon.spec.ImageProcessConfig;
public class ImageProcessPanel extends JPanel {
private final ImageProcessConfig mProcessConfig;
private JLabel mHorizontalDepthLabel;
private JSpinner mHorizontalDepthSpinner;
private JLabel mVerticalDepthLabel;
private JSpinner mVerticalDepthSpinner;
private JLabel mHorizontalGapLabel;
private JSpinner mHorizontalGapSpinner;
private JLabel mVerticalGapLabel;
private JSpinner mVerticalGapSpinner;
private JLabel mOverlapLabel;
private JSpinner mOverlapSpinner;
private JLabel mBlackborderDetectorLabel;
private JComboBox<String> mBlackborderDetectorCombo;
public ImageProcessPanel(ImageProcessConfig pProcessConfig) {
super();
mProcessConfig = pProcessConfig;
initialise();
}
@Override
@Transient
public Dimension getMaximumSize() {
Dimension maxSize = super.getMaximumSize();
Dimension prefSize = super.getPreferredSize();
return new Dimension(maxSize.width, prefSize.height);
}
private void initialise() {
setBorder(BorderFactory.createTitledBorder("Image Process"));
mHorizontalDepthLabel = new JLabel("Horizontal depth [%]:");
add(mHorizontalDepthLabel);
mHorizontalDepthSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mHorizontalDepth*100.0, 1.0, 100.0, 1.0));
mHorizontalDepthSpinner.addChangeListener(mChangeListener);
add(mHorizontalDepthSpinner);
mVerticalDepthLabel = new JLabel("Vertical depth [%]:");
add(mVerticalDepthLabel);
mVerticalDepthSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mVerticalDepth*100.0, 1.0, 100.0, 1.0));
mVerticalDepthSpinner.addChangeListener(mChangeListener);
add(mVerticalDepthSpinner);
mHorizontalGapLabel = new JLabel("Horizontal gap [%]:");
add(mHorizontalGapLabel);
mHorizontalGapSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mHorizontalGap*100.0, 0.0, 50.0, 1.0));
mHorizontalGapSpinner.addChangeListener(mChangeListener);
add(mHorizontalGapSpinner);
mVerticalGapLabel = new JLabel("Vertical gap [%]:");
add(mVerticalGapLabel);
mVerticalGapSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mVerticalGap*100.0, 0.0, 50.0, 1.0));
mVerticalGapSpinner.addChangeListener(mChangeListener);
add(mVerticalGapSpinner);
mOverlapLabel = new JLabel("Overlap [%]:");
add(mOverlapLabel);
mOverlapSpinner = new JSpinner(new SpinnerNumberModel(mProcessConfig.mOverlapFraction*100.0, -100.0, 100.0, 1.0));
mOverlapSpinner.addChangeListener(mChangeListener);
add(mOverlapSpinner);
mBlackborderDetectorLabel = new JLabel("Blackborder Detector:");
add(mBlackborderDetectorLabel);
mBlackborderDetectorCombo = new JComboBox<>(new String[] {"On", "Off"});
mBlackborderDetectorCombo.setSelectedItem(mProcessConfig.mBlackBorderRemoval?"On":"Off");
mBlackborderDetectorCombo.setToolTipText("Enables or disables the blackborder detection and removal");
mBlackborderDetectorCombo.addActionListener(mActionListener);
add(mBlackborderDetectorCombo);
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mHorizontalDepthLabel)
.addComponent(mVerticalDepthLabel)
.addComponent(mHorizontalGapLabel)
.addComponent(mVerticalGapLabel)
.addComponent(mOverlapLabel)
.addComponent(mBlackborderDetectorLabel)
)
.addGroup(layout.createParallelGroup()
.addComponent(mHorizontalDepthSpinner)
.addComponent(mVerticalDepthSpinner)
.addComponent(mHorizontalGapSpinner)
.addComponent(mVerticalGapSpinner)
.addComponent(mOverlapSpinner)
.addComponent(mBlackborderDetectorCombo)
)
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mHorizontalDepthLabel)
.addComponent(mHorizontalDepthSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mVerticalDepthLabel)
.addComponent(mVerticalDepthSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mHorizontalGapLabel)
.addComponent(mHorizontalGapSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mVerticalGapLabel)
.addComponent(mVerticalGapSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mOverlapLabel)
.addComponent(mOverlapSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mBlackborderDetectorLabel)
.addComponent(mBlackborderDetectorCombo)
)
);
}
private final ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Update the processing configuration
mProcessConfig.setBlackBorderRemoval((mBlackborderDetectorCombo.getSelectedItem() == "On"));
// Notify observers
mProcessConfig.notifyObservers(this);
}
};
private final ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
// Update the processing configuration
mProcessConfig.setHorizontalDepth(((Double)mHorizontalDepthSpinner.getValue())/100.0);
mProcessConfig.setVerticalDepth(((Double)mVerticalDepthSpinner.getValue())/100.0);
mProcessConfig.setHorizontalGap(((Double)mHorizontalGapSpinner.getValue())/100.0);
mProcessConfig.setVerticalGap(((Double)mVerticalGapSpinner.getValue())/100.0);
mProcessConfig.setOverlapFraction(((Double)mOverlapSpinner.getValue())/100.0);
// Notify observers
mProcessConfig.notifyObservers(this);
}
};
}

View File

@ -1,215 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.Transient;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.hyperion.hypercon.spec.MiscConfig;
public class InterfacePanel extends JPanel {
public final MiscConfig mMiscConfig;
private JPanel mJsonPanel;
private JCheckBox mJsonCheck;
private JLabel mJsonPortLabel;
private JSpinner mJsonPortSpinner;
private JPanel mProtoPanel;
private JCheckBox mProtoCheck;
private JLabel mProtoPortLabel;
private JSpinner mProtoPortSpinner;
private JPanel mBoblightPanel;
private JCheckBox mBoblightCheck;
private JLabel mBoblightPortLabel;
private JSpinner mBoblightPortSpinner;
public InterfacePanel(final MiscConfig pMiscConfig) {
super();
mMiscConfig = pMiscConfig;
initialise();
}
@Override
@Transient
public Dimension getMaximumSize() {
Dimension maxSize = super.getMaximumSize();
Dimension prefSize = super.getPreferredSize();
return new Dimension(maxSize.width, prefSize.height);
}
private void initialise() {
//setBorder(BorderFactory.createTitledBorder("External interfaces"));
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(getJsonPanel());
add(getProtoPanel());
add(getBoblightPanel());
toggleEnabledFlags();
}
private JPanel getJsonPanel() {
if (mJsonPanel == null) {
mJsonPanel = new JPanel();
mJsonPanel.setBorder(BorderFactory.createTitledBorder("Json server"));
mJsonCheck = new JCheckBox("Enabled");
mJsonCheck.setSelected(mMiscConfig.mJsonInterfaceEnabled);
mJsonCheck.addActionListener(mActionListener);
mJsonPanel.add(mJsonCheck);
mJsonPortLabel = new JLabel("TCP Port: ");
mJsonPanel.add(mJsonPortLabel);
mJsonPortSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mJsonPort, 1, 65536, 1));
mJsonPortSpinner.addChangeListener(mChangeListener);
mJsonPanel.add(mJsonPortSpinner);
GroupLayout layout = new GroupLayout(mJsonPanel);
layout.setAutoCreateGaps(true);
mJsonPanel.setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mJsonCheck)
.addComponent(mJsonPortLabel)
)
.addGroup(layout.createParallelGroup()
.addComponent(mJsonCheck)
.addComponent(mJsonPortSpinner)
));
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(mJsonCheck)
.addGroup(layout.createParallelGroup()
.addComponent(mJsonPortLabel)
.addComponent(mJsonPortSpinner)
));
}
return mJsonPanel;
}
private JPanel getProtoPanel() {
if (mProtoPanel == null) {
mProtoPanel = new JPanel();
mProtoPanel.setBorder(BorderFactory.createTitledBorder("Proto server"));
mProtoCheck = new JCheckBox("Enabled");
mProtoCheck.setSelected(mMiscConfig.mProtoInterfaceEnabled);
mProtoCheck.addActionListener(mActionListener);
mProtoPanel.add(mProtoCheck);
mProtoPortLabel = new JLabel("TCP Port: ");
mProtoPanel.add(mProtoPortLabel);
mProtoPortSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mProtoPort, 1, 65536, 1));
mProtoPortSpinner.addChangeListener(mChangeListener);
mProtoPanel.add(mProtoPortSpinner);
GroupLayout layout = new GroupLayout(mProtoPanel);
layout.setAutoCreateGaps(true);
mProtoPanel.setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mProtoCheck)
.addComponent(mProtoPortLabel)
)
.addGroup(layout.createParallelGroup()
.addComponent(mProtoCheck)
.addComponent(mProtoPortSpinner)
));
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(mProtoCheck)
.addGroup(layout.createParallelGroup()
.addComponent(mProtoPortLabel)
.addComponent(mProtoPortSpinner)
));
}
return mProtoPanel;
}
private JPanel getBoblightPanel() {
if (mBoblightPanel == null) {
mBoblightPanel = new JPanel();
mBoblightPanel.setBorder(BorderFactory.createTitledBorder("Boblight server"));
mBoblightCheck = new JCheckBox("Enabled");
mBoblightCheck.setSelected(mMiscConfig.mBoblightInterfaceEnabled);
mBoblightCheck.addActionListener(mActionListener);
mBoblightPanel.add(mBoblightCheck);
mBoblightPortLabel = new JLabel("TCP Port: ");
mBoblightPanel.add(mBoblightPortLabel);
mBoblightPortSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mBoblightPort, 1, 65536, 1));
mBoblightPortSpinner.addChangeListener(mChangeListener);
mBoblightPanel.add(mBoblightPortSpinner);
GroupLayout layout = new GroupLayout(mBoblightPanel);
layout.setAutoCreateGaps(true);
mBoblightPanel.setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mBoblightCheck)
.addComponent(mBoblightPortLabel)
)
.addGroup(layout.createParallelGroup()
.addComponent(mBoblightCheck)
.addComponent(mBoblightPortSpinner)
));
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(mBoblightCheck)
.addGroup(layout.createParallelGroup()
.addComponent(mBoblightPortLabel)
.addComponent(mBoblightPortSpinner)
));
}
return mBoblightPanel;
}
private void toggleEnabledFlags() {
mJsonPortLabel.setEnabled(mMiscConfig.mJsonInterfaceEnabled);
mJsonPortSpinner.setEnabled(mMiscConfig.mJsonInterfaceEnabled);
mProtoPortLabel.setEnabled(mMiscConfig.mProtoInterfaceEnabled);
mProtoPortSpinner.setEnabled(mMiscConfig.mProtoInterfaceEnabled);
mBoblightPortLabel.setEnabled(mMiscConfig.mBoblightInterfaceEnabled);
mBoblightPortSpinner.setEnabled(mMiscConfig.mBoblightInterfaceEnabled);
}
private final ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mMiscConfig.mJsonInterfaceEnabled = mJsonCheck.isSelected();
mMiscConfig.mProtoInterfaceEnabled = mProtoCheck.isSelected();
mMiscConfig.mBoblightInterfaceEnabled = mBoblightCheck.isSelected();
toggleEnabledFlags();
}
};
private final ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mMiscConfig.mJsonPort = (Integer)mJsonPortSpinner.getValue();
mMiscConfig.mProtoPort = (Integer)mJsonPortSpinner.getValue();
mMiscConfig.mBoblightPort = (Integer)mJsonPortSpinner.getValue();
}
};
}

View File

@ -1,48 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.GridLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class LedDivideDialog extends JFrame {
private final int mLedCount;
private final int mTransformCount;
private JPanel mContentPanel;
public LedDivideDialog(int pLedCnt, int pTransformCnt) {
super();
mLedCount = pLedCnt;
mTransformCount = pTransformCnt;
initialise();
}
private void initialise() {
mContentPanel = new JPanel();
mContentPanel.setLayout(new GridLayout(mLedCount, mTransformCount, 5, 5));
for (int iLed=0; iLed<mLedCount; ++iLed) {
ButtonGroup ledGroup = new ButtonGroup();
for (int iTransform=0; iTransform<mTransformCount; ++iTransform) {
JRadioButton ledTransformButton = new JRadioButton();
ledGroup.add(ledTransformButton);
mContentPanel.add(ledTransformButton);
}
}
setContentPane(mContentPanel);
}
public static void main(String[] pArgs) {
LedDivideDialog dialog = new LedDivideDialog(50, 3);
dialog.setSize(600, 800);
dialog.setVisible(true);
}
}

View File

@ -1,186 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.Transient;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.hyperion.hypercon.spec.LedFrameConstruction;
import org.hyperion.hypercon.spec.LedFrameConstruction.Direction;
public class LedFramePanel extends JPanel {
private final LedFrameConstruction mLedFrameSpec;
private JLabel mHorizontalCountLabel;
private JSpinner mHorizontalCountSpinner;
private JLabel mBottomGapCountLabel;
private JSpinner mBottomGapCountSpinner;
private JLabel mVerticalCountLabel;
private JSpinner mVerticalCountSpinner;
private JLabel mTopCornerLabel;
private JComboBox<Boolean> mTopCornerCombo;
private JLabel mBottomCornerLabel;
private JComboBox<Boolean> mBottomCornerCombo;
private JLabel mDirectionLabel;
private JComboBox<LedFrameConstruction.Direction> mDirectionCombo;
private JLabel mOffsetLabel;
private JSpinner mOffsetSpinner;
public LedFramePanel(LedFrameConstruction ledFrameSpec) {
super();
mLedFrameSpec = ledFrameSpec;
initialise();
}
@Override
@Transient
public Dimension getMaximumSize() {
Dimension maxSize = super.getMaximumSize();
Dimension prefSize = super.getPreferredSize();
return new Dimension(maxSize.width, prefSize.height);
}
private void initialise() {
setBorder(BorderFactory.createTitledBorder("Construction"));
mTopCornerLabel = new JLabel("Led in top corners");
add(mTopCornerLabel);
mTopCornerCombo = new JComboBox<>(new Boolean[] {true, false});
mTopCornerCombo.setSelectedItem(mLedFrameSpec.topCorners);
mTopCornerCombo.addActionListener(mActionListener);
add(mTopCornerCombo);
mBottomCornerLabel = new JLabel("Led in bottom corners");
add(mBottomCornerLabel);
mBottomCornerCombo = new JComboBox<>(new Boolean[] {true, false});
mBottomCornerCombo.setSelectedItem(mLedFrameSpec.bottomCorners);
mBottomCornerCombo.addActionListener(mActionListener);
add(mBottomCornerCombo);
mDirectionLabel = new JLabel("Direction");
add(mDirectionLabel);
mDirectionCombo = new JComboBox<>(LedFrameConstruction.Direction.values());
mDirectionCombo.setSelectedItem(mLedFrameSpec.clockwiseDirection?Direction.clockwise:Direction.counter_clockwise);
mDirectionCombo.addActionListener(mActionListener);
add(mDirectionCombo);
mHorizontalCountLabel = new JLabel("Horizontal #:");
add(mHorizontalCountLabel);
mHorizontalCountSpinner = new JSpinner(new SpinnerNumberModel(mLedFrameSpec.topLedCnt, 0, 1024, 1));
mHorizontalCountSpinner.addChangeListener(mChangeListener);
add(mHorizontalCountSpinner);
mBottomGapCountLabel = new JLabel("Bottom Gap #:");
add(mBottomGapCountLabel);
mBottomGapCountSpinner = new JSpinner(new SpinnerNumberModel(mLedFrameSpec.topLedCnt - mLedFrameSpec.bottomLedCnt, 0, 1024, 1));
mBottomGapCountSpinner.addChangeListener(mChangeListener);
add(mBottomGapCountSpinner);
mVerticalCountLabel = new JLabel("Vertical #:");
add(mVerticalCountLabel);
mVerticalCountSpinner = new JSpinner(new SpinnerNumberModel(mLedFrameSpec.rightLedCnt, 0, 1024, 1));
mVerticalCountSpinner.addChangeListener(mChangeListener);
add(mVerticalCountSpinner);
mOffsetLabel = new JLabel("1st LED offset");
add(mOffsetLabel);
mOffsetSpinner = new JSpinner(new SpinnerNumberModel(mLedFrameSpec.firstLedOffset, Integer.MIN_VALUE, Integer.MAX_VALUE, 1));
mOffsetSpinner.addChangeListener(mChangeListener);
add(mOffsetSpinner);
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mDirectionLabel)
.addComponent(mTopCornerLabel)
.addComponent(mBottomCornerLabel)
.addComponent(mHorizontalCountLabel)
.addComponent(mBottomGapCountLabel)
.addComponent(mVerticalCountLabel)
.addComponent(mOffsetLabel))
.addGroup(layout.createParallelGroup()
.addComponent(mDirectionCombo)
.addComponent(mTopCornerCombo)
.addComponent(mBottomCornerCombo)
.addComponent(mHorizontalCountSpinner)
.addComponent(mBottomGapCountSpinner)
.addComponent(mVerticalCountSpinner)
.addComponent(mOffsetSpinner))
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mDirectionLabel)
.addComponent(mDirectionCombo))
.addGroup(layout.createParallelGroup()
.addComponent(mTopCornerLabel)
.addComponent(mTopCornerCombo))
.addGroup(layout.createParallelGroup()
.addComponent(mBottomCornerLabel)
.addComponent(mBottomCornerCombo))
.addGroup(layout.createParallelGroup()
.addComponent(mHorizontalCountLabel)
.addComponent(mHorizontalCountSpinner))
.addGroup(layout.createParallelGroup()
.addComponent(mVerticalCountLabel)
.addComponent(mVerticalCountSpinner))
.addGroup(layout.createParallelGroup()
.addComponent(mBottomGapCountLabel)
.addComponent(mBottomGapCountSpinner))
.addGroup(layout.createParallelGroup()
.addComponent(mOffsetLabel)
.addComponent(mOffsetSpinner)));
}
void updateLedConstruction() {
mLedFrameSpec.topCorners = (Boolean)mTopCornerCombo.getSelectedItem();
mLedFrameSpec.bottomCorners = (Boolean)mBottomCornerCombo.getSelectedItem();
mLedFrameSpec.clockwiseDirection = ((LedFrameConstruction.Direction)mDirectionCombo.getSelectedItem()) == LedFrameConstruction.Direction.clockwise;
mLedFrameSpec.firstLedOffset = (Integer)mOffsetSpinner.getValue();
mLedFrameSpec.topLedCnt = (Integer)mHorizontalCountSpinner.getValue();
mLedFrameSpec.bottomLedCnt = Math.max(0, mLedFrameSpec.topLedCnt - (Integer)mBottomGapCountSpinner.getValue());
mLedFrameSpec.rightLedCnt = (Integer)mVerticalCountSpinner.getValue();
mLedFrameSpec.leftLedCnt = (Integer)mVerticalCountSpinner.getValue();
mLedFrameSpec.setChanged();
mLedFrameSpec.notifyObservers();
mBottomGapCountSpinner.setValue(mLedFrameSpec.topLedCnt - mLedFrameSpec.bottomLedCnt);
}
private final ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateLedConstruction();
}
};
private final ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
updateLedConstruction();
}
};
}

View File

@ -1,330 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.URL;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import org.hyperion.hypercon.LedFrameFactory;
import org.hyperion.hypercon.spec.ImageProcessConfig;
import org.hyperion.hypercon.spec.Led;
import org.hyperion.hypercon.spec.LedFrameConstruction;
public class LedSimulationComponent extends JPanel {
private BufferedImage mTvImage = new BufferedImage(640, 480, BufferedImage.TYPE_INT_ARGB);
private void setImage(Image pImage) {
mTvImage.createGraphics().drawImage(pImage, 0, 0, mTvImage.getWidth(), mTvImage.getHeight(), null);
}
{
Image image = new ImageIcon(LedSimulationComponent.class.getResource("TestImage_01.png")).getImage();
mTvImage.createGraphics().drawImage(image, 0, 0, mTvImage.getWidth(), mTvImage.getHeight(), null);
}
private JPanel mTopPanel;
private ImageComponent mTopLeftImage;
private ImageComponent mTopImage;
private ImageComponent mTopRightImage;
private ImageComponent mLeftImage;
private ImageComponent mRightImage;
private JPanel mBottomPanel;
private ImageComponent mBottomLeftImage;
private ImageComponent mBottomImage;
private ImageComponent mBottomRightImage;
private JProgressBar mProgressBar;
LedTvComponent mTvComponent;
private int mLedCnt = 0;
public LedSimulationComponent(Vector<Led> pLeds) {
super();
initialise(pLeds);
setLeds(pLeds);
}
void initialise(Vector<Led> pLeds) {
setBackground(Color.BLACK);
setLayout(new BorderLayout());
add(getTopPanel(), BorderLayout.NORTH);
mLeftImage = new ImageComponent();
mLeftImage.setPreferredSize(new Dimension(100,100));
add(mLeftImage, BorderLayout.WEST);
mRightImage = new ImageComponent();
mRightImage.setPreferredSize(new Dimension(100,100));
add(mRightImage, BorderLayout.EAST);
add(getBottomPanel(), BorderLayout.SOUTH);
mTvComponent = new LedTvComponent(pLeds);
mTvComponent.setImage(mTvImage);
add(mTvComponent, BorderLayout.CENTER);
mTvComponent.addMouseListener(mPopupListener);
}
private JPanel getTopPanel() {
mTopPanel = new JPanel();
mTopPanel.setPreferredSize(new Dimension(100,100));
mTopPanel.setBackground(Color.BLACK);
mTopPanel.setLayout(new BorderLayout());
mTopLeftImage = new ImageComponent();
mTopLeftImage.setPreferredSize(new Dimension(100,100));
mTopPanel.add(mTopLeftImage, BorderLayout.WEST);
mTopImage = new ImageComponent();
mTopPanel.add(mTopImage, BorderLayout.CENTER);
mTopRightImage = new ImageComponent();
mTopRightImage.setPreferredSize(new Dimension(100,100));
mTopPanel.add(mTopRightImage, BorderLayout.EAST);
return mTopPanel;
}
private JPanel getBottomPanel() {
mBottomPanel = new JPanel();
mBottomPanel.setPreferredSize(new Dimension(100,100));
mBottomPanel.setBackground(Color.BLACK);
mBottomPanel.setLayout(new BorderLayout());
mBottomLeftImage = new ImageComponent();
mBottomLeftImage.setPreferredSize(new Dimension(100,100));
mBottomPanel.add(mBottomLeftImage, BorderLayout.WEST);
mBottomImage = new ImageComponent();
mBottomPanel.add(mBottomImage, BorderLayout.CENTER);
mBottomRightImage = new ImageComponent();
mBottomRightImage.setPreferredSize(new Dimension(100,100));
mBottomPanel.add(mBottomRightImage, BorderLayout.EAST);
mProgressBar = new JProgressBar(0, 100);
mBottomPanel.add(mProgressBar, BorderLayout.SOUTH);
return mBottomPanel;
}
LedSimulationWorker mWorker = null;
public void setLeds(Vector<Led> pLeds) {
mLedCnt = pLeds == null? 0 : pLeds.size();
mTvComponent.setLeds(pLeds);
synchronized (LedSimulationComponent.this) {
if (mWorker != null) {
mWorker.cancel(true);
}
mWorker = null;
}
mWorker = new LedSimulationWorker(mTvImage, pLeds);
mProgressBar.setValue(0);
mWorker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName() == "state") {
if (evt.getNewValue() == SwingWorker.StateValue.STARTED) {
mProgressBar.setVisible(true);
} else if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
handleWorkerDone();
mProgressBar.setVisible(false);
}
} else if (evt.getPropertyName() == "progress") {
mProgressBar.setValue(mWorker.getProgress());
}
}
private void handleWorkerDone() {
BufferedImage backgroundImage = null;
synchronized(LedSimulationComponent.this) {
if (mWorker == null) {
return;
}
try {
backgroundImage = mWorker.get();
mWorker = null;
} catch (Exception e) {}
}
if (backgroundImage == null) {
return;
}
int width = backgroundImage.getWidth();
int height = backgroundImage.getHeight();
int borderWidth = (int) (backgroundImage.getWidth() * 0.1);
int borderHeight = (int) (backgroundImage.getHeight() * 0.2);
mTopLeftImage.setImage(backgroundImage.getSubimage(0, 0, borderWidth, borderHeight));
mTopImage.setImage(backgroundImage.getSubimage(borderWidth, 0, width-2*borderWidth, borderHeight));
mTopRightImage.setImage(backgroundImage.getSubimage(width-borderWidth, 0, borderWidth, borderHeight));
mLeftImage.setImage(backgroundImage.getSubimage(0, borderHeight, borderWidth, height-2*borderHeight));
mRightImage.setImage(backgroundImage.getSubimage(width-borderWidth, borderHeight, borderWidth, height-2*borderHeight));
mBottomLeftImage.setImage(backgroundImage.getSubimage(0, height-borderHeight, borderWidth, borderHeight));
mBottomImage.setImage(backgroundImage.getSubimage(borderWidth, height-borderHeight, width-2*borderWidth, borderHeight));
mBottomRightImage.setImage(backgroundImage.getSubimage(width-borderWidth, height-borderHeight, borderWidth, borderHeight));
mProgressBar.setValue(100);
mProgressBar.setVisible(false);
mWorker = null;
LedSimulationComponent.this.repaint();
}
});
mWorker.execute();
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D gCopy = (Graphics2D)g.create();
gCopy.setXORMode(Color.WHITE);
gCopy.setFont(gCopy.getFont().deriveFont(20.0f));
String ledCntStr = "Led count: " + mLedCnt;
gCopy.drawString(ledCntStr, getWidth()-150.0f, getHeight()-10.0f);
}
public static void main(String[] pArgs) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(800, 600);
Vector<Led> leds = LedFrameFactory.construct(new LedFrameConstruction(), new ImageProcessConfig());
LedSimulationComponent ledSimComp = new LedSimulationComponent(leds);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(ledSimComp);
frame.setVisible(true);
}
private final MouseListener mPopupListener = new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
showPopup(e);
}
@Override
public void mousePressed(MouseEvent e) {
showPopup(e);
}
private void showPopup(MouseEvent e) {
if (!e.isPopupTrigger()) {
return;
}
getPopupMenu().show(mTvComponent, e.getX(), e.getY());
}
};
private JPopupMenu mPopupMenu;
private final Action mLoadAction = new AbstractAction("Load image...") {
JFileChooser mImageChooser;
@Override
public void actionPerformed(ActionEvent e) {
if (mImageChooser == null) {
mImageChooser = new JFileChooser();
}
if (mImageChooser.showOpenDialog(mTvComponent) != JFileChooser.APPROVE_OPTION) {
return;
}
File file = mImageChooser.getSelectedFile();
try {
ImageIcon imageIcon = new ImageIcon(file.getAbsolutePath());
Image image = imageIcon.getImage();
mTvComponent.setImage(image);
// setIma
} catch (Exception ex) {
}
}
};
private synchronized JPopupMenu getPopupMenu() {
if (mPopupMenu == null) {
mPopupMenu = new JPopupMenu();
mPopupMenu.add(mLoadAction);
JMenu selectMenu = new JMenu("Select Image");
selectMenu.add(new SelectImageAction("TestImage_01"));
selectMenu.add(new SelectImageAction("TestImage_02"));
selectMenu.add(new SelectImageAction("TestImage_03"));
selectMenu.add(new SelectImageAction("TestImage_04"));
selectMenu.add(new SelectImageAction("TestImage_05"));
selectMenu.add(new SelectImageAction("TestImageBBB_01"));
selectMenu.add(new SelectImageAction("TestImageBBB_02"));
selectMenu.add(new SelectImageAction("TestImageBBB_03"));
mPopupMenu.add(selectMenu);
}
return mPopupMenu;
}
private class SelectImageAction extends AbstractAction {
private final String mImageName;
SelectImageAction(String pImageName) {
super(pImageName);
mImageName = pImageName;
ImageIcon image = loadImage();
if (image != null) {
Image scaledImage = image.getImage().getScaledInstance(32, 18, Image.SCALE_SMOOTH);
ImageIcon scaledIcon = new ImageIcon(scaledImage, mImageName);
putValue(SMALL_ICON, scaledIcon);
}
}
@Override
public void actionPerformed(ActionEvent e) {
ImageIcon imageIcon = loadImage();
if (imageIcon != null) {
Image image = imageIcon.getImage();
setImage(image);
mTvComponent.setImage(image);
repaint();
}
}
ImageIcon loadImage() {
URL imageUrl = LedSimulationComponent.class.getResource(mImageName + ".png");
if (imageUrl == null) {
System.out.println("Failed to load image: " + mImageName);
return null;
}
return new ImageIcon(imageUrl);
}
}
}

View File

@ -1,134 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.Vector;
import javax.swing.SwingWorker;
import org.hyperion.hypercon.spec.Led;
public class LedSimulationWorker extends SwingWorker<BufferedImage, Object> {
private final BufferedImage mTvImage;
private final Vector<Led> mLeds;
public LedSimulationWorker(BufferedImage pTvImage, Vector<Led> pLeds) {
super();
mTvImage = pTvImage;
mLeds = pLeds;
}
class LedPaint {
int color;
Point point;
double angle_rad;
}
private final List<LedPaint> mLedPaints = new Vector<>();
@Override
protected BufferedImage doInBackground() throws Exception {
Dimension imageDim = new Dimension(1280, 720);
BufferedImage backgroundImage = new BufferedImage(imageDim.width, imageDim.height, BufferedImage.TYPE_INT_ARGB);
mLedPaints.clear();
setProgress(5);
int imageWidth = mTvImage.getWidth();
int imageHeight = mTvImage.getHeight();
for (Led led : mLeds) {
LedPaint ledPaint = new LedPaint();
// Determine the location and orientation of the led on the image
ledPaint.point = tv2image(imageDim, led.mLocation);
ledPaint.angle_rad = 0.5*Math.PI - led.mSide.getAngle_rad();
// Determine the color of the led
int xMin = (int)(led.mImageRectangle.getMinX() * (imageWidth-1));
int xMax = (int)(led.mImageRectangle.getMaxX() * (imageWidth-1));
int yMin = (int)(led.mImageRectangle.getMinY() * (imageHeight-1));
int yMax = (int)(led.mImageRectangle.getMaxY() * (imageHeight-1));
ledPaint.color = determineColor(xMin, xMax, yMin, yMax);
mLedPaints.add(ledPaint);
}
setProgress(10);
Graphics2D g2d = backgroundImage.createGraphics();
// Clear the image with a black rectangle
g2d.setColor(Color.BLACK);
g2d.drawRect(0, 0, backgroundImage.getWidth(), backgroundImage.getHeight());
paintAllLeds(g2d);
return backgroundImage;
}
Point tv2image(Dimension pImageDim, Point2D point) {
double tvWidthFraction = (1.0 - 2*0.1);
double tvHeightFraction = (1.0 - 2*0.2);
double tvWidth = tvWidthFraction * pImageDim.width;
double tvXIndex = point.getX()*tvWidth;
double imageXIndex = tvXIndex + 0.1*pImageDim.width;
double tvHeight = tvHeightFraction * pImageDim.height;
double tvYIndex = point.getY()*tvHeight;
double imageYIndex = tvYIndex + 0.2*pImageDim.height;
return new Point((int)imageXIndex, (int)imageYIndex);
}
private int determineColor(int xMin, int xMax, int yMin, int yMax) {
int red = 0;
int green = 0;
int blue = 0;
int count = 0;
for (int y = yMin; y <= yMax; ++y) {
for (int x = xMin; x <= xMax; ++x) {
int color = mTvImage.getRGB(x, y);
red += (color >> 16) & 0xFF;
green += (color >> 8) & 0xFF;
blue += color & 0xFF;
++count;
}
}
return count > 0 ? new Color(red / count, green/count, blue/count).getRGB() : 0;
}
private void paintAllLeds(Graphics2D g2d) {
for (int i=2; i<=180; i+=4) {
if (isCancelled()) {
return;
}
int arcSize = 24 + (int)((i/12.0)*(i/12.0));
for(LedPaint led : mLedPaints) {
int argb = 0x05000000 | (0x00ffffff & led.color);
g2d.setColor(new Color(argb , true));
g2d.translate(led.point.getX(), led.point.getY());
g2d.rotate(led.angle_rad);
g2d.fillArc(-arcSize, -arcSize, 2*arcSize, 2*arcSize, 90-(i/2), i);
g2d.rotate(-led.angle_rad);
g2d.translate(-led.point.getX(), -led.point.getY());
setProgress(10+i/3);
}
}
}
}

View File

@ -1,134 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Vector;
import javax.swing.JComponent;
import org.hyperion.hypercon.spec.Led;
public class LedTvComponent extends JComponent {
private final BufferedImage mDisplayedImage = new BufferedImage(1280, 720, BufferedImage.TYPE_INT_ARGB);
private final Graphics2D mImageG2d = mDisplayedImage.createGraphics();
private final int mBorderWidth = 12;
private Vector<Led> mLeds;
private Led mSelectedLed;
public LedTvComponent(Vector<Led> pLeds) {
mLeds = pLeds;
addMouseMotionListener(mMouseMotionListener);
}
public void setLeds(Vector<Led> pLeds) {
mLeds = pLeds;
}
public void setImage(Image pImage) {
mImageG2d.clearRect(0, 0, mDisplayedImage.getWidth(), mDisplayedImage.getHeight());
mImageG2d.drawImage(pImage, 0,0, mDisplayedImage.getWidth(), mDisplayedImage.getHeight(), null);
}
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.DARK_GRAY.darker());
g2d.fillRect(0,0, getWidth()-1, getHeight()-1);
g2d.drawImage(mDisplayedImage, mBorderWidth, mBorderWidth, getWidth()-2*mBorderWidth, getHeight()-2*mBorderWidth, null);
if (mLeds == null) {
return;
}
g2d.setColor(Color.GRAY);
for (Led led : mLeds) {
Rectangle rect = led2tv(led.mImageRectangle);
g2d.drawRect(rect.x, rect.y, rect.width, rect.height);
switch (led.mSide) {
case top_left:
g2d.drawString(""+led.mLedSeqNr, 0, 11);
break;
case top:
g2d.drawString(""+led.mLedSeqNr, (int)rect.getCenterX(), 11);
break;
case top_right:
g2d.drawString(""+led.mLedSeqNr, (int)getWidth()-11, (int)11);
break;
case right:
g2d.drawString(""+led.mLedSeqNr, (int)getWidth()-11, (int)rect.getCenterY());
break;
case bottom_right:
g2d.drawString(""+led.mLedSeqNr, (int)getWidth()-11, (int)getHeight()-1);
break;
case bottom:
g2d.drawString(""+led.mLedSeqNr, (int)rect.getCenterX(), (int)getHeight()-1);
break;
case bottom_left:
g2d.drawString(""+led.mLedSeqNr, (int)0, (int)getHeight()-1);
break;
case left:
g2d.drawString(""+led.mLedSeqNr, 0, (int)rect.getCenterY());
break;
}
}
if (mSelectedLed != null) {
Rectangle rect = led2tv(mSelectedLed.mImageRectangle);
g2d.setStroke(new BasicStroke(3.0f));
g2d.setColor(Color.WHITE);
g2d.drawRect(rect.x, rect.y, rect.width, rect.height);
}
}
public Rectangle led2tv(Rectangle2D pLedRect) {
int tvWidth = getWidth()-2*mBorderWidth;
int tvHeight = getHeight()-2*mBorderWidth;
int x = (int) Math.round(mBorderWidth + tvWidth*pLedRect.getX());
int y = (int) Math.round(mBorderWidth + tvHeight*pLedRect.getY());
int width = (int) Math.round(tvWidth * pLedRect.getWidth());
int height = (int) Math.round(tvHeight * pLedRect.getHeight());
return new Rectangle(x,y, width, height);
}
private final MouseMotionListener mMouseMotionListener = new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
mSelectedLed = null;
double x = (double)(e.getX() - mBorderWidth) / (getWidth() - mBorderWidth*2);
double y = (double)(e.getY() - mBorderWidth) / (getHeight() - mBorderWidth*2);
for (Led led : mLeds) {
if (led.mImageRectangle.contains(x, y) || (Math.abs(led.mLocation.getX() - x) < 0.01 && Math.abs(led.mLocation.getY() - y) < 0.01)) {
mSelectedLed = led;
break;
}
}
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
}
};
}

View File

@ -1 +0,0 @@
d37be0ef34a74fb15c9ec81e9ebadb57de62d294

View File

@ -1 +0,0 @@
1df18121f930623884da3de93f146f93d11f621c

View File

@ -1 +0,0 @@
97019f8cd170a7792bb81ae09efd690669eef567

View File

@ -1 +0,0 @@
b607e73b98996bfa40d19d508be01919552552d0

View File

@ -1 +0,0 @@
0d3aafb4a85649e53888a660b87de98f59f0ec32

View File

@ -1 +0,0 @@
7962c1194cb2a2b7af6c3b34151701e113f00087

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1 +0,0 @@
ad1aba652ea186845d0c340cbeca7efb9d662e10

View File

@ -1,263 +0,0 @@
package org.hyperion.hypercon.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.Transient;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.hyperion.hypercon.spec.MiscConfig;
public class XbmcPanel extends JPanel {
private final MiscConfig mMiscConfig;
private JCheckBox mXbmcCheck;
private JLabel mAddressLabel;
private JTextField mAddressField;
private JLabel mTcpPortLabel;
private JSpinner mTcpPortSpinner;
private JLabel mMenuLabel;
private JComboBox<String> mMenuCombo;
private JLabel mVideoLabel;
private JComboBox<String> mVideoCombo;
private JLabel mPictureLabel;
private JComboBox<String> mPictureCombo;
private JLabel mAudioLabel;
private JComboBox<String> mAudioCombo;
private JLabel mScreensaverLabel;
private JComboBox<String> mScreensaverCombo;
private JLabel mEnable3DLabel;
private JComboBox<String> mEnable3DCombo;
public XbmcPanel(final MiscConfig pMiscConfig) {
super();
mMiscConfig = pMiscConfig;
initialise();
}
@Override
@Transient
public Dimension getMaximumSize() {
Dimension maxSize = super.getMaximumSize();
Dimension prefSize = super.getPreferredSize();
return new Dimension(maxSize.width, prefSize.height);
}
private void initialise() {
setBorder(BorderFactory.createTitledBorder("XBMC Checker"));
mXbmcCheck = new JCheckBox("Enabled");
mXbmcCheck.setSelected(mMiscConfig.mXbmcCheckerEnabled);
mXbmcCheck.addActionListener(mActionListener);
add(mXbmcCheck);
mAddressLabel = new JLabel("Server address:");
add(mAddressLabel);
mAddressField = new JTextField(mMiscConfig.mXbmcAddress);
mAddressField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
mMiscConfig.mXbmcAddress = mAddressField.getText();
}
@Override
public void insertUpdate(DocumentEvent e) {
mMiscConfig.mXbmcAddress = mAddressField.getText();
}
@Override
public void changedUpdate(DocumentEvent e) {
mMiscConfig.mXbmcAddress = mAddressField.getText();
}
});
add(mAddressField);
mTcpPortLabel = new JLabel("TCP port:");
add(mTcpPortLabel);
mTcpPortSpinner = new JSpinner(new SpinnerNumberModel(mMiscConfig.mXbmcTcpPort, 1, 65535, 1));
mTcpPortSpinner.addChangeListener(mChangeListener);
add(mTcpPortSpinner);
mMenuLabel = new JLabel("XBMC Menu");
add(mMenuLabel);
mMenuCombo = new JComboBox<>(new String[] {"On", "Off"});
mMenuCombo.setSelectedItem(mMiscConfig.mMenuOn? "On": "Off");
mMenuCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light in the XBMC Menu");
mMenuCombo.addActionListener(mActionListener);
add(mMenuCombo);
mVideoLabel = new JLabel("Video");
add(mVideoLabel);
mVideoCombo = new JComboBox<>(new String[] {"On", "Off"});
mVideoCombo.setSelectedItem(mMiscConfig.mVideoOn? "On": "Off");
mVideoCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light during video playback");
mVideoCombo.addActionListener(mActionListener);
add(mVideoCombo);
mPictureLabel = new JLabel("Picture");
add(mPictureLabel);
mPictureCombo = new JComboBox<>(new String[] {"On", "Off"});
mPictureCombo.setSelectedItem(mMiscConfig.mPictureOn? "On": "Off");
mPictureCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light when viewing pictures");
mPictureCombo.addActionListener(mActionListener);
add(mPictureCombo);
mAudioLabel = new JLabel("Audio");
add(mAudioLabel);
mAudioCombo = new JComboBox<>(new String[] {"On", "Off"});
mAudioCombo.setSelectedItem(mMiscConfig.mAudioOn? "On": "Off");
mAudioCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light when listing to audio");
mAudioCombo.addActionListener(mActionListener);
add(mAudioCombo);
mScreensaverLabel = new JLabel("Screensaver");
add(mScreensaverLabel);
mScreensaverCombo = new JComboBox<>(new String[] {"On", "Off"});
mScreensaverCombo.setSelectedItem(mMiscConfig.mScreensaverOn? "On": "Off");
mScreensaverCombo.setToolTipText("Enables('On') or disables('Off') the ambi-light when the XBMC screensaver is active");
mScreensaverCombo.addActionListener(mActionListener);
add(mScreensaverCombo);
mEnable3DLabel = new JLabel("3D checking");
add(mEnable3DLabel);
mEnable3DCombo = new JComboBox<>(new String[] {"On", "Off"});
mEnable3DCombo.setSelectedItem(mMiscConfig.m3DCheckingEnabled ? "On": "Off");
mEnable3DCombo.setToolTipText("Enables('On') or disables('Off') switching to 3D mode when a 3D video file is started");
mEnable3DCombo.addActionListener(mActionListener);
add(mEnable3DCombo);
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mXbmcCheck)
.addComponent(mAddressLabel)
.addComponent(mTcpPortLabel)
.addComponent(mMenuLabel)
.addComponent(mVideoLabel)
.addComponent(mPictureLabel)
.addComponent(mAudioLabel)
.addComponent(mScreensaverLabel)
.addComponent(mEnable3DLabel)
)
.addGroup(layout.createParallelGroup()
.addComponent(mXbmcCheck)
.addComponent(mAddressField)
.addComponent(mTcpPortSpinner)
.addComponent(mMenuCombo)
.addComponent(mVideoCombo)
.addComponent(mPictureCombo)
.addComponent(mAudioCombo)
.addComponent(mScreensaverCombo)
.addComponent(mEnable3DCombo)
));
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(mXbmcCheck)
.addGroup(layout.createParallelGroup()
.addComponent(mAddressLabel)
.addComponent(mAddressField)
)
.addGroup(layout.createParallelGroup()
.addComponent(mTcpPortLabel)
.addComponent(mTcpPortSpinner)
)
.addGroup(layout.createParallelGroup()
.addComponent(mMenuLabel)
.addComponent(mMenuCombo)
)
.addGroup(layout.createParallelGroup()
.addComponent(mVideoLabel)
.addComponent(mVideoCombo)
)
.addGroup(layout.createParallelGroup()
.addComponent(mPictureLabel)
.addComponent(mPictureCombo)
)
.addGroup(layout.createParallelGroup()
.addComponent(mAudioLabel)
.addComponent(mAudioCombo)
)
.addGroup(layout.createParallelGroup()
.addComponent(mScreensaverLabel)
.addComponent(mScreensaverCombo)
)
.addGroup(layout.createParallelGroup()
.addComponent(mEnable3DLabel)
.addComponent(mEnable3DCombo)
));
toggleEnabled(mMiscConfig.mXbmcCheckerEnabled);
}
private void toggleEnabled(boolean pEnabled) {
mAddressLabel.setEnabled(pEnabled);
mAddressField.setEnabled(pEnabled);
mTcpPortSpinner.setEnabled(pEnabled);
mTcpPortLabel.setEnabled(pEnabled);
mMenuLabel.setEnabled(pEnabled);
mMenuCombo.setEnabled(pEnabled);
mVideoLabel.setEnabled(pEnabled);
mVideoCombo.setEnabled(pEnabled);
mPictureLabel.setEnabled(pEnabled);
mPictureCombo.setEnabled(pEnabled);
mAudioLabel.setEnabled(pEnabled);
mAudioCombo.setEnabled(pEnabled);
mScreensaverLabel.setEnabled(pEnabled);
mScreensaverCombo.setEnabled(pEnabled);
mEnable3DLabel.setEnabled(pEnabled);
mEnable3DCombo.setEnabled(pEnabled);
}
private final ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mMiscConfig.mXbmcTcpPort = (Integer)mTcpPortSpinner.getValue();
}
};
private final ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mMiscConfig.mXbmcCheckerEnabled = mXbmcCheck.isSelected();
mMiscConfig.mMenuOn = (mMenuCombo.getSelectedItem() == "On");
mMiscConfig.mVideoOn = (mVideoCombo.getSelectedItem() == "On");
mMiscConfig.mPictureOn = (mPictureCombo.getSelectedItem() == "On");
mMiscConfig.mAudioOn = (mAudioCombo.getSelectedItem() == "On");
mMiscConfig.mScreensaverOn = (mScreensaverCombo.getSelectedItem() == "On");
mMiscConfig.m3DCheckingEnabled = (mEnable3DCombo.getSelectedItem() == "On");
toggleEnabled(mMiscConfig.mXbmcCheckerEnabled);
}
};
}

View File

@ -1,24 +0,0 @@
package org.hyperion.hypercon.gui.device;
import java.awt.Dimension;
import javax.swing.JPanel;
import org.hyperion.hypercon.spec.DeviceConfig;
public abstract class DeviceTypePanel extends JPanel {
protected final Dimension firstColMinDim = new Dimension(80, 10);
protected final Dimension maxDim = new Dimension(1024, 20);
protected DeviceConfig mDeviceConfig = null;
public DeviceTypePanel() {
super();
}
public void setDeviceConfig(DeviceConfig pDeviceConfig) {
mDeviceConfig = pDeviceConfig;
}
}

View File

@ -1,63 +0,0 @@
package org.hyperion.hypercon.gui.device;
import javax.swing.GroupLayout;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.hyperion.hypercon.spec.DeviceConfig;
public class LightPackPanel extends DeviceTypePanel {
private JLabel mSerialNoLabel;
private JTextField mSerialNoField;
public LightPackPanel() {
super();
initialise();
}
@Override
public void setDeviceConfig(DeviceConfig pDeviceConfig) {
super.setDeviceConfig(pDeviceConfig);
mSerialNoField.setText(mDeviceConfig.mOutput);
}
private void initialise() {
mSerialNoLabel = new JLabel("Serial #: ");
mSerialNoLabel.setMinimumSize(firstColMinDim);
add(mSerialNoLabel);
mSerialNoField = new JTextField();
mSerialNoField.setMaximumSize(maxDim);
mSerialNoField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
mDeviceConfig.mOutput = mSerialNoField.getText();
}
@Override
public void insertUpdate(DocumentEvent e) {
mDeviceConfig.mOutput = mSerialNoField.getText();
}
@Override
public void changedUpdate(DocumentEvent e) {
mDeviceConfig.mOutput = mSerialNoField.getText();
}
});
add(mSerialNoField);
GroupLayout layout = new GroupLayout(this);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(mSerialNoLabel)
.addComponent(mSerialNoField));
layout.setVerticalGroup(layout.createParallelGroup()
.addComponent(mSerialNoLabel)
.addComponent(mSerialNoField));
}
}

View File

@ -1,104 +0,0 @@
package org.hyperion.hypercon.gui.device;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.hyperion.hypercon.spec.DeviceConfig;
/**
* Panel for configuring Ws2801 specific settings
*/
public class SerialPanel extends DeviceTypePanel {
public static final String[] KnownOutputs = { "/dev/ttyS0", "/dev/ttyUSB0", "/dev/ttyAMA0", "/dev/null"};
private JLabel mOutputLabel;
private JComboBox<String> mOutputCombo;
private JLabel mBaudrateLabel;
private JSpinner mBaudrateSpinner;
public SerialPanel() {
super();
initialise();
}
@Override
public void setDeviceConfig(DeviceConfig pDeviceConfig) {
super.setDeviceConfig(pDeviceConfig);
mOutputCombo.setSelectedItem(mDeviceConfig.mOutput);
((SpinnerNumberModel)mBaudrateSpinner.getModel()).setValue(mDeviceConfig.mBaudrate);
}
private void initialise() {
mOutputLabel = new JLabel("Output: ");
mOutputLabel.setMinimumSize(firstColMinDim);
add(mOutputLabel);
mOutputCombo = new JComboBox<>(KnownOutputs);
mOutputCombo.setMaximumSize(maxDim);
mOutputCombo.setEditable(true);
mOutputCombo.addActionListener(mActionListener);
add(mOutputCombo);
mBaudrateLabel = new JLabel("Baudrate: ");
mBaudrateLabel.setMinimumSize(firstColMinDim);
add(mBaudrateLabel);
mBaudrateSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 1000000, 128));
mBaudrateSpinner .setMaximumSize(maxDim);
mBaudrateSpinner.addChangeListener(mChangeListener);
add(mBaudrateSpinner);
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mOutputLabel)
.addComponent(mBaudrateLabel))
.addGroup(layout.createParallelGroup()
.addComponent(mOutputCombo)
.addComponent(mBaudrateSpinner))
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mOutputLabel)
.addComponent(mOutputCombo))
.addGroup(layout.createParallelGroup()
.addComponent(mBaudrateLabel)
.addComponent(mBaudrateSpinner))
);
}
private ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == mOutputCombo) {
mDeviceConfig.mOutput = (String)mOutputCombo.getSelectedItem();
} else if (e.getSource() == mBaudrateSpinner) {
mDeviceConfig.mBaudrate = (Integer)mBaudrateSpinner.getValue();
}
}
};
private ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mDeviceConfig.mBaudrate = (Integer)mBaudrateSpinner.getValue();
}
};
}

View File

@ -1,63 +0,0 @@
package org.hyperion.hypercon.gui.device;
import javax.swing.GroupLayout;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.hyperion.hypercon.spec.DeviceConfig;
public class TestDevicePanel extends DeviceTypePanel {
private JLabel mFilenameLabel;
private JTextField mFilenameField;
public TestDevicePanel() {
super();
initialise();
}
@Override
public void setDeviceConfig(DeviceConfig pDeviceConfig) {
super.setDeviceConfig(pDeviceConfig);
mFilenameField.setText(mDeviceConfig.mOutput);
}
private void initialise() {
mFilenameLabel = new JLabel("Filename: ");
mFilenameLabel.setMinimumSize(firstColMinDim);
add(mFilenameLabel);
mFilenameField = new JTextField();
mFilenameField.setMaximumSize(maxDim);
mFilenameField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
mDeviceConfig.mOutput = mFilenameField.getText();
}
@Override
public void insertUpdate(DocumentEvent e) {
mDeviceConfig.mOutput = mFilenameField.getText();
}
@Override
public void changedUpdate(DocumentEvent e) {
mDeviceConfig.mOutput = mFilenameField.getText();
}
});
add(mFilenameField);
GroupLayout layout = new GroupLayout(this);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(mFilenameLabel)
.addComponent(mFilenameField));
layout.setVerticalGroup(layout.createParallelGroup()
.addComponent(mFilenameLabel)
.addComponent(mFilenameField));
}
}

View File

@ -1,104 +0,0 @@
package org.hyperion.hypercon.gui.device;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.hyperion.hypercon.spec.DeviceConfig;
/**
* Panel for configuring Ws2801 specific settings
*/
public class Ws2801Panel extends DeviceTypePanel {
public static final String[] KnownOutputs = {"/dev/spidev0.0", "/dev/spidev0.1", "/dev/null"};
private JLabel mOutputLabel;
private JComboBox<String> mOutputCombo;
private JLabel mBaudrateLabel;
private JSpinner mBaudrateSpinner;
public Ws2801Panel() {
super();
initialise();
}
@Override
public void setDeviceConfig(DeviceConfig pDeviceConfig) {
super.setDeviceConfig(pDeviceConfig);
mOutputCombo.setSelectedItem(mDeviceConfig.mOutput);
((SpinnerNumberModel)mBaudrateSpinner.getModel()).setValue(mDeviceConfig.mBaudrate);
}
private void initialise() {
mOutputLabel = new JLabel("Output: ");
mOutputLabel.setMinimumSize(firstColMinDim);
add(mOutputLabel);
mOutputCombo = new JComboBox<>(KnownOutputs);
mOutputCombo.setMaximumSize(maxDim);
mOutputCombo.setEditable(true);
mOutputCombo.addActionListener(mActionListener);
add(mOutputCombo);
mBaudrateLabel = new JLabel("Baudrate: ");
mBaudrateLabel.setMinimumSize(firstColMinDim);
add(mBaudrateLabel);
mBaudrateSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 1000000, 128));
mBaudrateSpinner.setMaximumSize(maxDim);
mBaudrateSpinner.addChangeListener(mChangeListener);
add(mBaudrateSpinner);
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
setLayout(layout);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mOutputLabel)
.addComponent(mBaudrateLabel))
.addGroup(layout.createParallelGroup()
.addComponent(mOutputCombo)
.addComponent(mBaudrateSpinner))
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(mOutputLabel)
.addComponent(mOutputCombo))
.addGroup(layout.createParallelGroup()
.addComponent(mBaudrateLabel)
.addComponent(mBaudrateSpinner))
);
}
private ActionListener mActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == mOutputCombo) {
mDeviceConfig.mOutput = (String)mOutputCombo.getSelectedItem();
} else if (e.getSource() == mBaudrateSpinner) {
mDeviceConfig.mBaudrate = (Integer)mBaudrateSpinner.getValue();
}
}
};
private ChangeListener mChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mDeviceConfig.mBaudrate = (Integer)mBaudrateSpinner.getValue();
}
};
}

View File

@ -1,37 +0,0 @@
package org.hyperion.hypercon.spec;
/**
* Enumeration of possible led-locations (aka border-sides). This also contains the specification of
* the angle at which the led is placed along a specific border (0.0rad = pointing right).
*/
public enum BorderSide {
top_left (0.75*Math.PI),
top(0.5*Math.PI),
top_right(0.25*Math.PI),
right(0.0*Math.PI),
bottom_right(-0.25*Math.PI),
bottom(-0.5*Math.PI),
bottom_left(-0.75*Math.PI),
left(1.0*Math.PI);
/** The angle of the led [rad] */
private final double mAngle_rad;
/**
* Constructs the BorderSide with the given led angle
*
* @param pAngle_rad The angle of the led [rad]
*/
BorderSide(double pAngle_rad) {
mAngle_rad = pAngle_rad;
}
/**
* Returns the angle of the led placement
*
* @return The angle of the led [rad]
*/
public double getAngle_rad() {
return mAngle_rad;
}
}

View File

@ -1,5 +0,0 @@
package org.hyperion.hypercon.spec;
public enum ColorByteOrder {
RGB, RBG, BRG, BGR, GRB, GBR
}

View File

@ -1,98 +0,0 @@
package org.hyperion.hypercon.spec;
import java.util.Locale;
import java.util.Vector;
/**
* The color tuning parameters of the different color channels (both in RGB space as in HSV space)
*/
public class ColorConfig {
/** List with color transformations */
public Vector<TransformConfig> mTransforms = new Vector<>();
{
mTransforms.add(new TransformConfig());
}
public boolean mSmoothingEnabled = false;
/** The type of smoothing algorithm */
public ColorSmoothingType mSmoothingType = ColorSmoothingType.linear;
/** The time constant for smoothing algorithm in milliseconds */
public int mSmoothingTime_ms = 200;
/** The update frequency of the leds in Hz */
public double mSmoothingUpdateFrequency_Hz = 20.0;
/**
* Creates the JSON string of the configuration as used in the Hyperion daemon configfile
*
* @return The JSON string of this ColorConfig
*/
public String toJsonString() {
StringBuffer strBuf = new StringBuffer();
strBuf.append("\t/// Color manipulation configuration used to tune the output colors to specific surroundings. \n");
strBuf.append("\t/// The configuration contains a list of color-transforms. Each transform contains the \n");
strBuf.append("\t/// following fields:\n");
strBuf.append("\t/// * 'id' : The unique identifier of the color transformation (eg 'device_1')");
strBuf.append("\t/// * 'leds' : The indices (or index ranges) of the leds to which this color transform applies\n");
strBuf.append("\t/// (eg '0-5, 9, 11, 12-17'). The indices are zero based.");
strBuf.append("\t/// * 'hsv' : The manipulation in the Hue-Saturation-Value color domain with the following \n");
strBuf.append("\t/// tuning parameters:\n");
strBuf.append("\t/// - 'saturationGain' The gain adjustement of the saturation\n");
strBuf.append("\t/// - 'valueGain' The gain adjustement of the value\n");
strBuf.append("\t/// * 'red'/'green'/'blue' : The manipulation in the Red-Green-Blue color domain with the \n");
strBuf.append("\t/// following tuning parameters for each channel:\n");
strBuf.append("\t/// - 'threshold' The minimum required input value for the channel to be on \n");
strBuf.append("\t/// (else zero)\n");
strBuf.append("\t/// - 'gamma' The gamma-curve correction factor\n");
strBuf.append("\t/// - 'blacklevel' The lowest possible value (when the channel is black)\n");
strBuf.append("\t/// - 'whitelevel' The highest possible value (when the channel is white)\n");
strBuf.append("\t///\n");
strBuf.append("\t/// Next to the list with color transforms there is also a smoothing option.\n");
strBuf.append("\t/// * 'smoothing' : Smoothing of the colors in the time-domain with the following tuning \n");
strBuf.append("\t/// parameters:\n");
strBuf.append("\t/// - 'type' The type of smoothing algorithm ('linear' or 'none')\n");
strBuf.append("\t/// - 'time_ms' The time constant for smoothing algorithm in milliseconds\n");
strBuf.append("\t/// - 'updateFrequency' The update frequency of the leds in Hz\n");
strBuf.append("\t\"color\" :\n");
strBuf.append("\t{\n");
strBuf.append("\t\t\"transform\" :\n");
strBuf.append("\t\t[\n");
for (int i=0; i<mTransforms.size(); ++i) {
TransformConfig transform = mTransforms.get(i);
strBuf.append(transform.toJsonString());
if (i == mTransforms.size()-1) {
strBuf.append("\n");
} else {
strBuf.append(",\n");
}
}
strBuf.append("\t\t],\n");
strBuf.append(smoothingToString() + "\n");
strBuf.append("\t}");
return strBuf.toString();
}
/**
* Creates the JSON string of the smoothing subconfiguration as used in the Hyperion deamon configfile
*
* @return The JSON string of the HSV-config
*/
private String smoothingToString() {
StringBuffer strBuf = new StringBuffer();
String preamble = "\t\t";
strBuf.append(preamble).append("\"smoothing\" :\n");
strBuf.append(preamble).append("{\n");
strBuf.append(preamble).append(String.format(Locale.ROOT, "\t\"type\" : \"%s\",\n", (mSmoothingEnabled) ? mSmoothingType.name() : "none"));
strBuf.append(preamble).append(String.format(Locale.ROOT, "\t\"time_ms\" : %d,\n", mSmoothingTime_ms));
strBuf.append(preamble).append(String.format(Locale.ROOT, "\t\"updateFrequency\" : %.4f\n", mSmoothingUpdateFrequency_Hz));
strBuf.append(preamble).append("}");
return strBuf.toString();
}
}

View File

@ -1,17 +0,0 @@
package org.hyperion.hypercon.spec;
public enum ColorSmoothingType {
/** Linear smoothing of led data */
linear("Linear smoothing");
private final String mName;
private ColorSmoothingType(String name) {
mName = name;
}
@Override
public String toString() {
return mName;
}
}

View File

@ -1,49 +0,0 @@
package org.hyperion.hypercon.spec;
/**
* The device specific configuration
*/
public class DeviceConfig {
/** The name of the device */
public String mName = "MyPi";
/** The type specification of the device */
public DeviceType mType = DeviceType.ws2801;
/** The device 'file' name */
public String mOutput = "/dev/spidev0.0";
/** The baudrate of the device */
public int mBaudrate = 250000;
/** The order of the color bytes */
public ColorByteOrder mColorByteOrder = ColorByteOrder.RGB;
/**
* Creates the JSON string of the configuration as used in the Hyperion daemon configfile
*
* @return The JSON string of this DeviceConfig
*/
public String toJsonString() {
StringBuffer strBuf = new StringBuffer();
strBuf.append("\t/// Device configuration contains the following fields: \n");
strBuf.append("\t/// * 'name' : The user friendly name of the device (only used for display purposes)\n");
strBuf.append("\t/// * 'type' : The type of the device or leds (known types for now are 'ws2801', 'ldp8806',\n");
strBuf.append("\t/// 'lpd6803', 'sedu', 'adalight', 'lightpack', 'test' and 'none')\n");
strBuf.append("\t/// * 'output' : The output specification depends on selected device. This can for example be the\n");
strBuf.append("\t/// device specifier, device serial number, or the output file name\n");
strBuf.append("\t/// * 'rate' : The baudrate of the output to the device\n");
strBuf.append("\t/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.).\n");
strBuf.append("\t\"device\" :\n");
strBuf.append("\t{\n");
strBuf.append("\t\t\"name\" : \"").append(mName).append("\",\n");
strBuf.append("\t\t\"type\" : \"").append(mType.name()).append("\",\n");
strBuf.append("\t\t\"output\" : \"").append(mOutput).append("\",\n");
strBuf.append("\t\t\"rate\" : ").append(mBaudrate).append(",\n");
strBuf.append("\t\t\"colorOrder\" : \"").append(mColorByteOrder.name().toLowerCase()).append("\"\n");
strBuf.append("\t}");
return strBuf.toString();
}
}

View File

@ -1,89 +0,0 @@
package org.hyperion.hypercon.spec;
import org.hyperion.hypercon.gui.device.DeviceTypePanel;
import org.hyperion.hypercon.gui.device.LightPackPanel;
import org.hyperion.hypercon.gui.device.SerialPanel;
import org.hyperion.hypercon.gui.device.TestDevicePanel;
import org.hyperion.hypercon.gui.device.Ws2801Panel;
/**
* Enumeration of known device types
*/
public enum DeviceType {
/** WS2801 Led String device with one continuous shift-register (1 byte per color-channel) */
ws2801("WS2801"),
/** LDP8806 Led String device with one continuous shift-register (1 + 7 bits per color channel)*/
lpd8806("LPD8806"),
/** LDP6803 Led String device with one continuous shift-register (5 bits per color channel)*/
lpd6803("LPD6803"),
/** SEDU LED device */
sedu("SEDU"),
/** Lightberry device */
lightberry("Lightberry"),
/** Adalight device */
adalight("Adalight"),
/** Lightpack USB led device */
lightpack("Lightpack"),
/** Paintpack USB led device */
paintpack("Paintpack"),
/** Test device for writing color values to file-output */
test("Test"),
/** No device, no output is generated */
none("None");
/** The 'pretty' name of the device type */
private final String mName;
/** The device specific configuration panel */
private DeviceTypePanel mConfigPanel;
/**
* Constructs the DeviceType
*
* @param name The 'pretty' name of the device type
* @param pConfigPanel The panel for device type specific configuration
*/
private DeviceType(final String name) {
mName = name;
}
/**
* Returns the configuration panel for the this device-type (or null if no configuration is required)
*
* @return The panel for configuring this device type
*/
public DeviceTypePanel getConfigPanel(DeviceConfig pDeviceConfig) {
if (mConfigPanel == null) {
switch (this) {
case ws2801:
case lightberry:
case lpd6803:
case lpd8806:
mConfigPanel = new Ws2801Panel();
break;
case test:
mConfigPanel = new TestDevicePanel();
break;
case adalight:
case sedu:
mConfigPanel = new SerialPanel();
break;
case lightpack:
mConfigPanel = new LightPackPanel();
break;
case paintpack:
case none:
break;
}
}
if (mConfigPanel != null) {
mConfigPanel.setDeviceConfig(pDeviceConfig);
}
return mConfigPanel;
}
@Override
public String toString() {
return mName;
}
}

View File

@ -1,175 +0,0 @@
package org.hyperion.hypercon.spec;
import java.util.Observable;
import org.hyperion.hypercon.JsonStringBuffer;
import org.hyperion.hypercon.LedFrameFactory;
/**
* Configuration parameters for the image processing. These settings are translated using the
* {@link LedFrameFactory} to configuration items used in the Hyperion daemon configfile.
*
*/
public class ImageProcessConfig extends Observable {
/** The 'integration depth' of the leds along the horizontal axis of the tv */
public double mHorizontalDepth = 0.08;
/** The 'integration depth' of the leds along the vertical axis of the tv */
public double mVerticalDepth = 0.05;
/** The gap between the border integration area for the horizontal leds */
public double mHorizontalGap = 0.0;
/** The gap between the border integration area for the vertical leds */
public double mVerticalGap = 0.0;
/** The fraction of overlap from one to another led */
public double mOverlapFraction = 0.0;
/** Flag indicating that black borders are excluded in the image processing */
public boolean mBlackBorderRemoval = true;
/**
* Returns the horizontal depth (top and bottom) of the image integration as a fraction of the
* image [0.0; 1.0]
*
* @return The horizontal integration depth [0.0; 1.0]
*/
public double getHorizontalDepth() {
return mHorizontalDepth;
}
/**
* Sets the horizontal depth (top and bottom) of the image integration as a fraction of the
* image [0.0; 1.0]
*
* @param pHorizontalDepth The horizontal integration depth [0.0; 1.0]
*/
public void setHorizontalDepth(double pHorizontalDepth) {
if (mHorizontalDepth != pHorizontalDepth) {
mHorizontalDepth = pHorizontalDepth;
setChanged();
}
}
/**
* Returns the horizontal gap (top and bottom) of the image integration area from the side of the
* screen [0.0; 1.0]
*
* @return The horizontal gap [0.0; 1.0]
*/
public double getHorizontalGap() {
return mHorizontalGap;
}
/**
* Sets the horizontal gap (top and bottom) of the image integration area from the side as a fraction of the
* screen [0.0; 1.0]
*
* @param pHorizontalGap The horizontal integration area gap from the side [0.0; 1.0]
*/
public void setHorizontalGap(double pHorizontalGap) {
if (mHorizontalGap != pHorizontalGap) {
mHorizontalGap = pHorizontalGap;
setChanged();
}
}
/**
* Returns the vertical depth (left and right) of the image integration as a fraction of the
* image [0.0; 1.0]
*
* @return The vertical integration depth [0.0; 1.0]
*/
public double getVerticalDepth() {
return mVerticalDepth;
}
/**
* Sets the vertical depth (left and right) of the image integration as a fraction of the
* image [0.0; 1.0]
*
* @param pVerticalDepth The vertical integration depth [0.0; 1.0]
*/
public void setVerticalDepth(double pVerticalDepth) {
if (mVerticalDepth != pVerticalDepth) {
mVerticalDepth = pVerticalDepth;
setChanged();
}
}
/**
* Returns the vertical gap (left and right) of the image integration area from the side of the
* screen [0.0; 1.0]
*
* @return The vertical gap [0.0; 1.0]
*/
public double getVerticalGap() {
return mVerticalGap;
}
/**
* Sets the horizontal gap (top and bottom) of the image integration area from the side as a fraction of the
* screen [0.0; 1.0]
*
* @param pHorizontalGap The horizontal integration area gap from the side [0.0; 1.0]
*/
public void setVerticalGap(double pVerticalGap) {
if (mVerticalGap != pVerticalGap) {
mVerticalGap = pVerticalGap;
setChanged();
}
}
/**
* Returns the fractional overlap of one integration tile with its neighbors
*
* @return The fractional overlap of the integration tiles
*/
public double getOverlapFraction() {
return mOverlapFraction;
}
/**
* Sets the fractional overlap of one integration tile with its neighbors
*
* @param pOverlapFraction The fractional overlap of the integration tiles
*/
public void setOverlapFraction(double pOverlapFraction) {
if (mOverlapFraction != pOverlapFraction) {
mOverlapFraction = pOverlapFraction;
setChanged();
}
}
/**
* Returns the black border removal flag
* @return True if black border removal is enabled else false
*/
public boolean isBlackBorderRemoval() {
return mBlackBorderRemoval;
}
/**
* Sets the black border removal flag
* @param pBlackBorderRemoval True if black border removal is enabled else false
*/
public void setBlackBorderRemoval(boolean pBlackBorderRemoval) {
if (mBlackBorderRemoval != pBlackBorderRemoval) {
mBlackBorderRemoval = pBlackBorderRemoval;
setChanged();
}
}
public void appendTo(JsonStringBuffer pJsonBuf) {
String comment =
"The black border configuration, contains the following items: \n" +
" * enable : true if the detector should be activated\n";
pJsonBuf.writeComment(comment);
pJsonBuf.startObject("blackborderdetector");
pJsonBuf.addValue("enable", mBlackBorderRemoval, true);
pJsonBuf.stopObject();
}
}

View File

@ -1,33 +0,0 @@
package org.hyperion.hypercon.spec;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* Led specification with fractional location along screen border and fractional-rectangle for
* integrating an image into led color
*/
public class Led {
/** The sequence number of the led */
public int mLedSeqNr;
/** The side along which the led is placed */
public BorderSide mSide;
/** The fractional location of the led */
public Point2D mLocation;
/** The fractional rectangle for image integration */
public Rectangle2D mImageRectangle;
/**
* String representation of the led specification
*
* @return The led specs as nice readable string
*/
@Override
public String toString() {
return "Led[" + mLedSeqNr + "] Location=" + mLocation + " Rectangle=" + mImageRectangle;
}
}

View File

@ -1,63 +0,0 @@
package org.hyperion.hypercon.spec;
import java.util.Observable;
/**
* The LedFrame describes the construction of leds along the sides of the TV screen.
*/
public class LedFrameConstruction extends Observable {
/**
* Enumeration of the led configuration direction
*/
public enum Direction {
/** Clockwise led configuration */
clockwise,
/** Counter Clockwise led configuration */
counter_clockwise;
}
/** True if the leds are organised clockwise else false (counter clockwise) */
public boolean clockwiseDirection = true;
/** True if the top corners have a led else false */
public boolean topCorners = true;
/** True if the bottom corners have a led else false */
public boolean bottomCorners = true;
/** The number of leds between the top-left corner and the top-right corner of the screen
(excluding the corner leds) */
public int topLedCnt = 16;
/** The number of leds between the bottom-left corner and the bottom-right corner of the screen
(excluding the corner leds) */
public int bottomLedCnt = 16;
/** The number of leds between the top-left corner and the bottom-left corner of the screen
(excluding the corner leds) */
public int leftLedCnt = 7;
/** The number of leds between the top-right corner and the bottom-right corner of the screen
(excluding the corner leds) */
public int rightLedCnt = 7;
/** The offset (in leds) of the starting led counted clockwise from the top-left corner */
public int firstLedOffset = -16;
/**
* Returns the total number of leds
*
* @return The total number of leds
*/
public int getLedCount() {
int cornerLedCnt = 0;
if (topCorners) cornerLedCnt+=2;
if (bottomCorners) cornerLedCnt+=2;
return topLedCnt + bottomLedCnt + leftLedCnt + rightLedCnt + cornerLedCnt;
}
@Override
public void setChanged() {
super.setChanged();
}
}

View File

@ -1,191 +0,0 @@
package org.hyperion.hypercon.spec;
import org.hyperion.hypercon.JsonStringBuffer;
/**
* Miscellaneous configuration items for the Hyperion daemon.
*/
public class MiscConfig {
/** The absolute location(s) of the effects */
public String mEffectEnginePath = "/opt/hyperion/effects";
/** Flag indicating that the boot sequence is enabled(true) or not(false) */
public boolean mBootSequenceEnabled = true;
/** The effect selected for the boot sequence */
public String mBootSequenceEffect = "Rainbow swirl fast";
/** The (maximum) length of the boot-sequence */
public int mBootSequenceLength_ms = 3000;
/** Flag indicating that the Frame Grabber is enabled */
public boolean mFrameGrabberEnabled = true;
/** The width of 'grabbed' frames (screen shots) [pixels] */
public int mFrameGrabberWidth = 64;
/** The height of 'grabbed' frames (screen shots) [pixels] */
public int mFrameGrabberHeight = 64;
/** The interval of frame grabs (screen shots) [ms] */
public int mFrameGrabberInterval_ms = 100;
/** Flag indicating that the XBMC checker is enabled */
public boolean mXbmcCheckerEnabled = true;
/** The IP-address of XBMC */
public String mXbmcAddress = "127.0.0.1";
/** The TCP JSON-Port of XBMC */
public int mXbmcTcpPort = 9090;
/** Flag indicating that the frame-grabber is on during video playback */
public boolean mVideoOn = true;
/** Flag indicating that the frame-grabber is on during XBMC menu */
public boolean mMenuOn = false;
/** Flag indicating that the frame-grabber is on during picture slideshow */
public boolean mPictureOn = true;
/** Flag indicating that the frame-grabber is on during audio playback */
public boolean mAudioOn = true;
/** Flag indicating that the frame-grabber is on when xbmc is on screensaver */
public boolean mScreensaverOn = true;
/** Flag indicating that the frame-grabber is should take actions when a 3D file is playing */
public boolean m3DCheckingEnabled = true;
/** Flag indicating that the JSON interface is enabled */
public boolean mJsonInterfaceEnabled = true;
/** The TCP port at which the JSON server is listening for incoming connections */
public int mJsonPort = 19444;
/** Flag indicating that the PROTO interface is enabled */
public boolean mProtoInterfaceEnabled = true;
/** The TCP port at which the Protobuf server is listening for incoming connections */
public int mProtoPort = 19445;
/** Flag indicating that the PROTO interface is enabled */
public boolean mBoblightInterfaceEnabled = false;
/** The TCP port at which the Protobuf server is listening for incoming connections */
public int mBoblightPort = 19333;
public void appendTo(JsonStringBuffer strBuf) {
String effectEngineComment =
"The configuration of the effect engine, contains the following items: \n" +
" * paths : An array with absolute location(s) of directories with effects \n" +
" * bootsequence : The effect selected as 'boot sequence'";
strBuf.writeComment(effectEngineComment);
String[] effectPaths = mEffectEnginePath.split(":");
strBuf.startObject("effects");
strBuf.startArray("paths");
for (String effectPath : effectPaths) {
strBuf.addArrayElement(effectPath, effectPath == effectPaths[effectPaths.length-1]);
}
strBuf.stopArray(true);
strBuf.stopObject();
strBuf.newLine();
strBuf.toggleComment(!mBootSequenceEnabled);
strBuf.startObject("bootsequence");
strBuf.addValue("effect", mBootSequenceEffect, false);
strBuf.addValue("duration_ms", mBootSequenceLength_ms, true);
strBuf.stopObject();
strBuf.toggleComment(false);
strBuf.newLine();
String grabComment =
" The configuration for the frame-grabber, contains the following items: \n" +
" * width : The width of the grabbed frames [pixels]\n" +
" * height : The height of the grabbed frames [pixels]\n" +
" * frequency_Hz : The frequency of the frame grab [Hz]\n";
strBuf.writeComment(grabComment);
strBuf.toggleComment(!mFrameGrabberEnabled);
strBuf.startObject("framegrabber");
strBuf.addValue("width", mFrameGrabberWidth, false);
strBuf.addValue("height", mFrameGrabberHeight, false);
strBuf.addValue("frequency_Hz", 1000.0/mFrameGrabberInterval_ms, true);
strBuf.stopObject();
strBuf.toggleComment(false);
strBuf.newLine();
String xbmcComment =
"The configuration of the XBMC connection used to enable and disable the frame-grabber. Contains the following fields: \n" +
" * xbmcAddress : The IP address of the XBMC-host\n" +
" * xbmcTcpPort : The TCP-port of the XBMC-server\n" +
" * grabVideo : Flag indicating that the frame-grabber is on(true) during video playback\n" +
" * grabPictures : Flag indicating that the frame-grabber is on(true) during picture show\n" +
" * grabAudio : Flag indicating that the frame-grabber is on(true) during audio playback\n" +
" * grabMenu : Flag indicating that the frame-grabber is on(true) in the XBMC menu\n" +
" * grabScreensaver : Flag indicating that the frame-grabber is on(true) when XBMC is on screensaver\n" +
" * enable3DDetection : Flag indicating that the frame-grabber should switch to a 3D compatible modus if a 3D video is playing\n";
strBuf.writeComment(xbmcComment);
strBuf.toggleComment(!mXbmcCheckerEnabled);
strBuf.startObject("xbmcVideoChecker");
strBuf.addValue("xbmcAddress", mXbmcAddress, false);
strBuf.addValue("xbmcTcpPort", mXbmcTcpPort, false);
strBuf.addValue("grabVideo", mVideoOn, false);
strBuf.addValue("grabPictures", mPictureOn, false);
strBuf.addValue("grabAudio", mAudioOn, false);
strBuf.addValue("grabMenu", mMenuOn, false);
strBuf.addValue("grabScreensaver", mScreensaverOn, false);
strBuf.addValue("enable3DDetection", m3DCheckingEnabled, true);
strBuf.stopObject();
strBuf.toggleComment(false);
strBuf.newLine();
String jsonComment =
"The configuration of the Json server which enables the json remote interface\n" +
" * port : Port at which the json server is started\n";
strBuf.writeComment(jsonComment);
strBuf.toggleComment(!mJsonInterfaceEnabled);
strBuf.startObject("jsonServer");
strBuf.addValue("port", mJsonPort, true);
strBuf.stopObject();
strBuf.toggleComment(false);
strBuf.newLine();
String protoComment =
"The configuration of the Proto server which enables the protobuffer remote interface\n" +
" * port : Port at which the protobuffer server is started\n";
strBuf.writeComment(protoComment);
strBuf.toggleComment(!mProtoInterfaceEnabled);
strBuf.startObject("protoServer");
strBuf.addValue("port", mProtoPort, true);
strBuf.stopObject();
strBuf.toggleComment(false);
strBuf.newLine();
String boblightComment =
"The configuration of the boblight server which enables the boblight remote interface\n" +
" * port : Port at which the boblight server is started\n";
strBuf.writeComment(boblightComment);
strBuf.toggleComment(!mBoblightInterfaceEnabled);
strBuf.startObject("boblightServer");
strBuf.addValue("port", mBoblightPort, true);
strBuf.stopObject();
strBuf.toggleComment(false);
}
/**
* Creates the JSON string of the configuration as used in the Hyperion daemon configfile
*
* @return The JSON string of this MiscConfig
*/
public String toJsonString() {
JsonStringBuffer jsonBuf = new JsonStringBuffer(1);
appendTo(jsonBuf);
return jsonBuf.toString();
}
public static void main(String[] pArgs) {
MiscConfig miscConfig = new MiscConfig();
JsonStringBuffer jsonBuf = new JsonStringBuffer(1);
miscConfig.appendTo(jsonBuf);
System.out.println(jsonBuf.toString());
}
}

View File

@ -1,111 +0,0 @@
package org.hyperion.hypercon.spec;
import java.util.Locale;
public class TransformConfig {
/** The identifier of this ColorTransform configuration */
public String mId = "default";
/** The indices to which this transform applies */
public String mLedIndexString = "*";
/** The saturation gain (in HSV space) */
public double mSaturationGain = 1.0;
/** The value gain (in HSV space) */
public double mValueGain = 1.0;
/** The minimum required RED-value (in RGB space) */
public double mRedThreshold = 0.0;
/** The gamma-curve correct for the RED-value (in RGB space) */
public double mRedGamma = 1.0;
/** The black-level of the RED-value (in RGB space) */
public double mRedBlacklevel = 0.0;
/** The white-level of the RED-value (in RGB space) */
public double mRedWhitelevel = 1.0;
/** The minimum required GREEN-value (in RGB space) */
public double mGreenThreshold = 0.0;
/** The gamma-curve correct for the GREEN-value (in RGB space) */
public double mGreenGamma = 1.0;
/** The black-level of the GREEN-value (in RGB space) */
public double mGreenBlacklevel = 0.0;
/** The white-level of the GREEN-value (in RGB space) */
public double mGreenWhitelevel = 1.0;
/** The minimum required BLUE-value (in RGB space) */
public double mBlueThreshold = 0.0;
/** The gamma-curve correct for the BLUE-value (in RGB space) */
public double mBlueGamma = 1.0;
/** The black-level of the BLUE-value (in RGB space) */
public double mBlueBlacklevel = 0.0;
/** The white-level of the BLUE-value (in RGB space) */
public double mBlueWhitelevel = 1.0;
public String toJsonString() {
StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\t\t{\n");
strBuf.append("\t\t\t\t\"id\" : \"" + mId + "\",\n");
strBuf.append("\t\t\t\t\"leds\" : \"" + mLedIndexString + "\",\n");
strBuf.append(hsvToJsonString() + ",\n");
strBuf.append(rgbToJsonString() + "\n");
strBuf.append("\t\t\t}");
return strBuf.toString();
}
/**
* Creates the JSON string of the HSV-subconfiguration as used in the Hyperion deamon configfile
*
* @return The JSON string of the HSV-config
*/
private String hsvToJsonString() {
StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\t\t\t\"hsv\" :\n");
strBuf.append("\t\t\t\t{\n");
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"saturationGain\" : %.4f,\n", mSaturationGain));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"valueGain\" : %.4f\n", mValueGain));
strBuf.append("\t\t\t\t}");
return strBuf.toString();
}
/**
* Creates the JSON string of the RGB-subconfiguration as used in the Hyperion deamon configfile
*
* @return The JSON string of the RGB-config
*/
private String rgbToJsonString() {
StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\t\t\t\"red\" :\n");
strBuf.append("\t\t\t\t{\n");
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"threshold\" : %.4f,\n", mRedThreshold));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"gamma\" : %.4f,\n", mRedGamma));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"blacklevel\" : %.4f,\n", mRedBlacklevel));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"whitelevel\" : %.4f\n", mRedWhitelevel));
strBuf.append("\t\t\t\t},\n");
strBuf.append("\t\t\t\t\"green\" :\n");
strBuf.append("\t\t\t\t{\n");
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"threshold\" : %.4f,\n", mGreenThreshold));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"gamma\" : %.4f,\n", mGreenGamma));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"blacklevel\" : %.4f,\n", mGreenBlacklevel));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"whitelevel\" : %.4f\n", mGreenWhitelevel));
strBuf.append("\t\t\t\t},\n");
strBuf.append("\t\t\t\t\"blue\" :\n");
strBuf.append("\t\t\t\t{\n");
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"threshold\" : %.4f,\n", mBlueThreshold));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"gamma\" : %.4f,\n", mBlueGamma));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"blacklevel\" : %.4f,\n", mBlueBlacklevel));
strBuf.append(String.format(Locale.ROOT, "\t\t\t\t\t\"whitelevel\" : %.4f\n", mBlueWhitelevel));
strBuf.append("\t\t\t\t}");
return strBuf.toString();
}
@Override
public String toString() {
return mId;
}
}

View File

@ -1,46 +0,0 @@
package org.hyperion.hypercon.test;
import org.hyperion.hypercon.ConfigurationFile;
import org.hyperion.hypercon.spec.ColorByteOrder;
import org.hyperion.hypercon.spec.ColorConfig;
import org.hyperion.hypercon.spec.DeviceConfig;
import org.hyperion.hypercon.spec.DeviceType;
import org.hyperion.hypercon.spec.ImageProcessConfig;
import org.hyperion.hypercon.spec.LedFrameConstruction;
import org.hyperion.hypercon.spec.MiscConfig;
public class TesConfigWriter {
public static void main(String[] pArgs) {
DeviceConfig deviceConfig = new DeviceConfig();
LedFrameConstruction frameConfig = new LedFrameConstruction();
ColorConfig colorConfig = new ColorConfig();
ImageProcessConfig imageConfig = new ImageProcessConfig();
MiscConfig miscConfig = new MiscConfig();
deviceConfig.mBaudrate = 4800;
deviceConfig.mColorByteOrder = ColorByteOrder.BGR;
deviceConfig.mName = "DAG";
deviceConfig.mOutput = "/dev/null";
deviceConfig.mType = DeviceType.lpd6803;
ConfigurationFile configFile = new ConfigurationFile();
configFile.store(deviceConfig);
configFile.store(frameConfig);
configFile.store(colorConfig);
configFile.store(imageConfig);
configFile.store(miscConfig);
configFile.save("./HyperCon.dat");
ConfigurationFile configFile2 = new ConfigurationFile();
configFile2.load("./HyperCon.dat");
configFile2.restore(deviceConfig);
configFile2.restore(frameConfig);
configFile2.restore(colorConfig);
configFile2.restore(imageConfig);
configFile2.restore(miscConfig);
System.out.println(configFile2);
}
}

View File

@ -102,9 +102,6 @@ int main(int argc, char** argv)
const unsigned duration_ms = effectConfig["duration_ms"].asUInt(); const unsigned duration_ms = effectConfig["duration_ms"].asUInt();
const int priority = 0; const int priority = 0;
// int retVal = -1;
// QMetaObject::invokeMethod(hyperion, "setEffect", Q_RETURN_ARG(int, retVal), Q_ARG(std::string, effectName), Q_ARG(Json::Value, Json::Value()), Q_ARG(int, priority), Q_ARG(int, duration_ms));
// if (retVal == 0)
if (hyperion.setEffect(effectName, priority, duration_ms) == 0) if (hyperion.setEffect(effectName, priority, duration_ms) == 0)
{ {
std::cout << "Boot sequence(" << effectName << ") created and started" << std::endl; std::cout << "Boot sequence(" << effectName << ") created and started" << std::endl;

View File

@ -1,11 +1,15 @@
# Needed for testing non-public components # Needed for testing non-public components
include_directories(../libsrc) include_directories(../libsrc)
# Add the simple test executable 'TestSpi' if(ENABLE_SPIDEV)
add_executable(test_spi # Add the simple test executable 'TestSpi'
TestSpi.cpp) add_executable(test_spi TestSpi.cpp)
target_link_libraries(test_spi target_link_libraries(test_spi hyperion)
hyperion)
add_executable(spidev_test spidev_test.c)
add_executable(gpio2spi switchPinCtrl.c)
endif(ENABLE_SPIDEV)
add_executable(test_configfile add_executable(test_configfile
TestConfigFile.cpp) TestConfigFile.cpp)
@ -49,9 +53,9 @@ add_executable(test_qregexp TestQRegExp.cpp)
target_link_libraries(test_qregexp target_link_libraries(test_qregexp
${QT_LIBRARIES}) ${QT_LIBRARIES})
add_executable(spidev_test spidev_test.c) add_executable(test_qtscreenshot TestQtScreenshot.cpp)
target_link_libraries(test_qtscreenshot
add_executable(gpio2spi switchPinCtrl.c) ${QT_LIBRARIES})
add_executable(determineWs2811Timing DetermineWs2811Timing.cpp) add_executable(determineWs2811Timing DetermineWs2811Timing.cpp)
@ -62,6 +66,9 @@ add_executable(test_rs232highspeed
target_link_libraries(test_rs232highspeed target_link_libraries(test_rs232highspeed
serialport) serialport)
include_directories(/usr/include) if(NOT APPLE AND UNIX)
add_executable(test_uartHighSpeed TestUartHighSpeed.cpp) include_directories(/usr/include)
target_link_libraries(test_uartHighSpeed ${QT_LIBRARIES}) add_executable(test_uartHighSpeed TestUartHighSpeed.cpp)
add_executable(test_nonInvWs2812b TestNonInvWs2812b.cpp)
endif()

View File

@ -49,6 +49,8 @@ int main()
requiredTiming(400, 850, 150, 5); // Zero requiredTiming(400, 850, 150, 5); // Zero
requiredTiming(800, 450, 150, 5); // One requiredTiming(800, 450, 150, 5); // One
requiredTiming(650, 600, 150, 5); // One
// 4bits // 4bits
requiredTiming(400, 850, 150, 4); // Zero requiredTiming(400, 850, 150, 4); // Zero
requiredTiming(800, 450, 150, 4); // One requiredTiming(800, 450, 150, 4); // One

138
test/TestNonInvWs2812b.cpp Normal file
View File

@ -0,0 +1,138 @@
// STL includes
#include <cstdint>
#include <vector>
#include <iostream>
std::vector<uint8_t> encode(const std::vector<uint8_t> & data);
void split(const uint8_t byte, uint8_t & out1, uint8_t & out2);
uint8_t encode(const bool bit1, const bool bit2, const bool bit3);
void print(uint8_t byte)
{
for (int i=0; i<8; ++i)
{
if (byte & (1 << i))
{
std::cout << '1';
}
else
{
std::cout << '0';
}
}
}
int main()
{
std::vector<uint8_t> data(3, 0x55);
std::vector<uint8_t> encData = encode(data);
for (uint8_t encByte : encData)
{
std::cout << "0 ";
print(encByte);
std::cout << " 1";
}
std::cout << std::endl;
return 0;
}
std::vector<uint8_t> encode(const std::vector<uint8_t> & data)
{
std::vector<uint8_t> result;
uint8_t previousByte = 0x00;
uint8_t nextByte = 0x00;
for (unsigned iData=0; iData<data.size(); iData+=3)
{
const uint8_t byte1 = data[iData];
const uint8_t byte2 = data[iData+1];
const uint8_t byte3 = data[iData+2];
uint8_t encByte;
encByte = encode(byte1 & 0x80, byte1 & 0x40, byte1 & 0x20);
std::cout << "Encoded byte 1: "; print(encByte); std::cout << std::endl;
split(encByte, previousByte, nextByte);
result.push_back(previousByte);
previousByte = nextByte;
encByte = encode(byte1 & 0x10, byte1 & 0x08, byte1 & 0x04);
split(encByte, previousByte, nextByte);
result.push_back(previousByte);
previousByte = nextByte;
encByte = encode(byte1 & 0x02, byte1 & 0x01, byte2 & 0x80);
split(encByte, previousByte, nextByte);
result.push_back(previousByte);
previousByte = nextByte;
encByte = encode(byte2 & 0x40, byte2 & 0x20, byte2 & 0x10);
split(encByte, previousByte, nextByte);
result.push_back(previousByte);
previousByte = nextByte;
encByte = encode(byte2 & 0x08, byte2 & 0x04, byte2 & 0x02);
split(encByte, previousByte, nextByte);
result.push_back(previousByte);
previousByte = nextByte;
encByte = encode(byte2 & 0x01, byte3 & 0x80, byte3 & 0x40);
split(encByte, previousByte, nextByte);
result.push_back(previousByte);
previousByte = nextByte;
encByte = encode(byte3 & 0x20, byte3 & 0x10, byte3 & 0x08);
split(encByte, previousByte, nextByte);
result.push_back(previousByte);
previousByte = nextByte;
encByte = encode(byte3 & 0x04, byte3 & 0x02, byte3 & 0x01);
split(encByte, previousByte, nextByte);
result.push_back(previousByte);
previousByte = nextByte;
}
return result;
}
void split(const uint8_t byte, uint8_t & out1, uint8_t & out2)
{
print(byte); std::cout << " => ";
print(out2); std::cout << " => ";
out1 &= ~0x0F;
out1 |= (byte & 0x0F) << 4;
// out2 &= ~0xF0;
print(out2); std::cout << " => ";
out2 = (byte & 0xF0) >> 4;
print(out2); std::cout << std::endl;
}
uint8_t encode(const bool bit1, const bool bit2, const bool bit3)
{
if (bit2)
{
uint8_t result = 0x19; // 0--1 01 10-1
if (bit1) result |= 0x02;
// else result &= ~0x02;
if (bit3) result |= 0x60;
// else result &= ~0x60;
return result;
}
else
{
uint8_t result = 0x21;// 0x21 (0-10 01 0--1)
if (bit1) result |= 0x06;
// else result &= ~0x06;
if (bit3) result |= 0x40;
// else result &= ~0x40;
return result;
}
}

20
test/TestQtScreenshot.cpp Normal file
View File

@ -0,0 +1,20 @@
// STL includes
#include <iostream>
// QT includes
#include <QApplication>
#include <QDesktopWidget>
#include <QPixmap>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QPixmap originalPixmap = QPixmap::grabWindow(QApplication::desktop()->winId());
std::cout << "Grabbed image: [" << originalPixmap.width() << "; " << originalPixmap.height() << "]" << std::endl;
return 0;
}

View File

@ -62,7 +62,9 @@ int testSerialPortLib()
continue; continue;
} }
rs232Port.flushOutput();
rs232Port.write(data); rs232Port.write(data);
rs232Port.flush();
data.clear(); data.clear();
for (int i=0; i<9; ++i) for (int i=0; i<9; ++i)
@ -110,7 +112,7 @@ public:
open(); open();
} }
int write(const std::vector<ColorRgb> &ledValues) \ int write(const std::vector<ColorRgb> &ledValues)
{ {
std::vector<uint8_t> bytes(ledValues.size() * 3 * 4); std::vector<uint8_t> bytes(ledValues.size() * 3 * 4);
@ -130,7 +132,7 @@ public:
return 0; return 0;
} }
int switchOff() { return 0; } int switchOff() { return 0; };
void writeTestSequence(const std::vector<uint8_t> & data) void writeTestSequence(const std::vector<uint8_t> & data)
{ {

View File

@ -12,8 +12,80 @@
#include <csignal> #include <csignal>
#include <cstdint> #include <cstdint>
#include <bitset> #include <bitset>
#include <vector>
#include <QElapsedTimer> #include <pthread.h>
#include <sched.h>
void set_realtime_priority() {
int ret;
// We'll operate on the currently running thread.
pthread_t this_thread = pthread_self();
// struct sched_param is used to store the scheduling priority
struct sched_param params;
// We'll set the priority to the maximum.
params.sched_priority = sched_get_priority_max(SCHED_FIFO);
std::cout << "Trying to set thread realtime prio = " << params.sched_priority << std::endl;
// Attempt to set thread real-time priority to the SCHED_FIFO policy
ret = pthread_setschedparam(this_thread, SCHED_FIFO, &params);
if (ret != 0) {
// Print the error
std::cout << "Unsuccessful in setting thread realtime prio (erno=" << ret << ")" << std::endl;
return;
}
// Now verify the change in thread priority
int policy = 0;
ret = pthread_getschedparam(this_thread, &policy, &params);
if (ret != 0) {
std::cout << "Couldn't retrieve real-time scheduling paramers" << std::endl;
return;
}
// Check the correct policy was applied
if(policy != SCHED_FIFO) {
std::cout << "Scheduling is NOT SCHED_FIFO!" << std::endl;
} else {
std::cout << "SCHED_FIFO OK" << std::endl;
}
// Print thread scheduling priority
std::cout << "Thread priority is " << params.sched_priority << std::endl;
}
struct ColorSignal
{
uint8_t green_1;
uint8_t green_2;
uint8_t green_3;
uint8_t green_4;
uint8_t red_1;
uint8_t red_2;
uint8_t red_3;
uint8_t red_4;
uint8_t blue_1;
uint8_t blue_2;
uint8_t blue_3;
uint8_t blue_4;
};
static ColorSignal RED_Signal = { 0xCE, 0xCE, 0xCE, 0xCE,
0xCE, 0x8C, 0x8C, 0x8C,
0xCE, 0xCE, 0xCE, 0xCE };
static ColorSignal GREEN_Signal = { 0xCE, 0x8C, 0x8C, 0x8C,
0xCE, 0xCE, 0xCE, 0xCE,
0xCE, 0xCE, 0xCE, 0xCE };
static ColorSignal BLUE_Signal = { 0xCE, 0xCE, 0xCE, 0xCE,
0xCE, 0xCE, 0xCE, 0xCE,
0xCE, 0x8C, 0x8C, 0x8C};
static ColorSignal BLACK_Signal = { 0xCE, 0xCE, 0xCE, 0xCE,
0xCE, 0xCE, 0xCE, 0xCE,
0xCE, 0xCE, 0xCE, 0xCE};
static volatile bool _running; static volatile bool _running;
@ -23,8 +95,16 @@ void signal_handler(int signum)
} }
void test3bitsEncoding();
int main() int main()
{ {
if (true)
{
test3bitsEncoding();
return 0;
}
_running = true; _running = true;
signal(SIGTERM, &signal_handler); signal(SIGTERM, &signal_handler);
@ -46,7 +126,7 @@ int main()
// immediately with a failure status if the output can't be written immediately. // immediately with a failure status if the output can't be written immediately.
// //
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process. // O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1) if (uart0_filestream == -1)
{ {
//ERROR - CAN'T OPEN SERIAL PORT //ERROR - CAN'T OPEN SERIAL PORT
@ -67,17 +147,18 @@ int main()
// PARODD - Odd parity (else even) // PARODD - Odd parity (else even)
struct termios options; struct termios options;
tcgetattr(uart0_filestream, &options); tcgetattr(uart0_filestream, &options);
options.c_cflag = B4000000 | CS8 | CLOCAL | CREAD; //<Set baud rate options.c_cflag = B4000000 | CS8 | CLOCAL; //<Set baud rate
options.c_iflag = IGNPAR; options.c_iflag = IGNPAR;
options.c_oflag = 0; options.c_oflag = 0;
options.c_lflag = 0; options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH); cfmakeraw(&options);
std::cout << "options.c_cflag = " << options.c_cflag << std::endl; std::cout << "options.c_cflag = " << options.c_cflag << std::endl;
std::cout << "options.c_iflag = " << options.c_iflag << std::endl; std::cout << "options.c_iflag = " << options.c_iflag << std::endl;
std::cout << "options.c_oflag = " << options.c_oflag << std::endl; std::cout << "options.c_oflag = " << options.c_oflag << std::endl;
std::cout << "options.c_lflag = " << options.c_lflag << std::endl; std::cout << "options.c_lflag = " << options.c_lflag << std::endl;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options); tcsetattr(uart0_filestream, TCSANOW, &options);
// Let's verify configured options // Let's verify configured options
tcgetattr(uart0_filestream, &options); tcgetattr(uart0_filestream, &options);
@ -128,47 +209,9 @@ int main()
} }
//----- TX BYTES ----- //----- TX BYTES -----
uint8_t tx_buffer[3*3*8*4]; std::vector<ColorSignal> signalData(10, RED_Signal);
uint8_t *p_tx_buffer;
// for (int i=0; i<3; ++i)
// {
// Writing 0xFF, 0x00, 0x00
// *p_tx_buffer++ = 0x8C;
// *p_tx_buffer++ = 0x8C;
// *p_tx_buffer++ = 0x8C;
// *p_tx_buffer++ = 0x8C;
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(1,2);
p_tx_buffer = &tx_buffer[0];
for (int i=0; i<9; ++i)
{
int coinFlip = distribution(generator);
if (coinFlip == 1)
{
*p_tx_buffer++ = 0xCE;
*p_tx_buffer++ = 0xCE;
*p_tx_buffer++ = 0xCE;
*p_tx_buffer++ = 0xCE;
}
else
{
*p_tx_buffer++ = 0x8C;
*p_tx_buffer++ = 0x8C;
*p_tx_buffer++ = 0x8C;
*p_tx_buffer++ = 0x8C;
}
}
std::cout << "Binary stream: [";
for (unsigned char* txIt=&(tx_buffer[0]); txIt!=p_tx_buffer; ++txIt)
{
std::cout << " 1 " << (std::bitset<8>) (*txIt) << " 0 ";
}
std::cout << "]" << std::endl;
int loopCnt = 0;
std::cout << "Type 'c' to continue, 'q' or 'x' to quit: "; std::cout << "Type 'c' to continue, 'q' or 'x' to quit: ";
while (_running) while (_running)
{ {
@ -182,38 +225,28 @@ int main()
continue; continue;
} }
int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0])); //Filestream, bytes to write, number of bytes to write set_realtime_priority();
if (count < 0) for (int iRun=0; iRun<10; ++iRun)
{ {
std::cerr << "UART TX error" << std::endl; // tcflush(uart0_filestream, TCOFLUSH);
write(uart0_filestream, signalData.data(), signalData.size()*sizeof(ColorSignal));
tcdrain(uart0_filestream);
//----- CLOSE THE UART ----- usleep(100000);
close(uart0_filestream); ++loopCnt;
return -1;
} if (loopCnt%3 == 2)
std::cout << "Writing " << count << " bytes to uart" << std::endl; signalData = std::vector<ColorSignal>(10, GREEN_Signal);
else if(loopCnt%3 == 1)
signalData = std::vector<ColorSignal>(10, BLUE_Signal);
else if(loopCnt%3 == 0)
signalData = std::vector<ColorSignal>(10, RED_Signal);
p_tx_buffer = &tx_buffer[0];
for (int i=0; i<9; ++i)
{
int coinFlip = distribution(generator);
if (coinFlip == 1)
{
*p_tx_buffer++ = 0xCE;
*p_tx_buffer++ = 0xCE;
*p_tx_buffer++ = 0xCE;
*p_tx_buffer++ = 0xCE;
}
else
{
*p_tx_buffer++ = 0x8C;
*p_tx_buffer++ = 0x8C;
*p_tx_buffer++ = 0x8C;
*p_tx_buffer++ = 0x8C;
}
} }
} }
signalData = std::vector<ColorSignal>(50, BLACK_Signal);
write(uart0_filestream, signalData.data(), signalData.size()*sizeof(ColorSignal));
//----- CLOSE THE UART ----- //----- CLOSE THE UART -----
close(uart0_filestream); close(uart0_filestream);
@ -221,3 +254,133 @@ int main()
return 0; return 0;
} }
std::vector<uint8_t> bit3Encode(const std::vector<uint8_t> & bytes);
uint8_t bit3Encode(const bool bit_1, const bool bit_2, const bool bit_3);
void test3bitsEncoding()
{
//OPEN THE UART
int uart0_filestream = open("/dev/ttyAMA0", O_WRONLY | O_NOCTTY | O_NDELAY);
if (uart0_filestream == -1)
{
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
return;
}
// Configure the port
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B2500000 | CS7 | CLOCAL;
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
std::vector<uint8_t> colorRed;
for (unsigned i=0; i<10; ++i)
{
colorRed.push_back(0x00);
colorRed.push_back(0xFF);
colorRed.push_back(0x00);
}
std::vector<uint8_t> colorGreen;
for (unsigned i=0; i<10; ++i)
{
colorGreen.push_back(0xFF);
colorGreen.push_back(0x00);
colorGreen.push_back(0x00);
}
std::vector<uint8_t> colorBlue;
for (unsigned i=0; i<10; ++i)
{
colorBlue.push_back(0x00);
colorBlue.push_back(0x00);
colorBlue.push_back(0xFF);
}
std::vector<uint8_t> colorBlack;
for (unsigned i=0; i<10; ++i)
{
colorBlack.push_back(0x00);
colorBlack.push_back(0x00);
colorBlack.push_back(0x00);
}
const std::vector<uint8_t> colorRedSignal = bit3Encode(colorRed);
const std::vector<uint8_t> colorGreenSignal = bit3Encode(colorGreen);
const std::vector<uint8_t> colorBlueSignal = bit3Encode(colorBlue);
const std::vector<uint8_t> colorBlackSignal = bit3Encode(colorBlack);
for (unsigned i=0; i<100; ++i)
{
size_t res;
res = write(uart0_filestream, colorRedSignal.data(), colorRedSignal.size());
(void)res;
usleep(100000);
res = write(uart0_filestream, colorGreenSignal.data(), colorGreenSignal.size());
(void)res;
usleep(100000);
res = write(uart0_filestream, colorBlueSignal.data(), colorBlueSignal.size());
(void)res;
usleep(100000);
}
size_t res = write(uart0_filestream, colorBlackSignal.data(), colorBlackSignal.size());
(void)res;
//----- CLOSE THE UART -----
res = close(uart0_filestream);
(void)res;
std::cout << "Program finished" << std::endl;
}
std::vector<uint8_t> bit3Encode(const std::vector<uint8_t> & bytes)
{
std::vector<uint8_t> result;
for (unsigned iByte=0; iByte<bytes.size(); iByte+=3)
{
const uint8_t & byte1 = bytes[iByte];
const uint8_t & byte2 = bytes[iByte + 1];
const uint8_t & byte3 = bytes[iByte + 2];
result.push_back(bit3Encode(byte1 & 0x80, byte1 & 0x40, byte1 & 0x20));
result.push_back(bit3Encode(byte1 & 0x10, byte1 & 0x08, byte1 & 0x04));
result.push_back(bit3Encode(byte1 & 0x02, byte1 & 0x01, byte2 & 0x80));
result.push_back(bit3Encode(byte2 & 0x40, byte2 & 0x20, byte2 & 0x10));
result.push_back(bit3Encode(byte2 & 0x08, byte2 & 0x04, byte2 & 0x02));
result.push_back(bit3Encode(byte2 & 0x01, byte3 & 0x80, byte3 & 0x40));
result.push_back(bit3Encode(byte3 & 0x20, byte3 & 0x10, byte3 & 0x08));
result.push_back(bit3Encode(byte3 & 0x04, byte3 & 0x02, byte3 & 0x01));
}
return result;
}
uint8_t bit3Encode(const bool bit_1, const bool bit_2, const bool bit_3)
{
// Bit index(default):1 2 3
// | | |
// default value (1) 00 100 10 (0)
//
// Reversed value (1) 01 001 00 (0)
// | | |
// Bit index (rev): 3 2 1
uint8_t result = 0x24;
if(bit_1)
{
result |= 0x01;
}
if (bit_2)
{
result |= 0x08;
}
if (bit_3)
{
result |= 0x40;
}
return ~result;
}