mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Merge branch 'master' into add_v4l
Former-commit-id: b3f1d532c6145ba80c161b18214de6efbc55ff7b
This commit is contained in:
commit
fdb140c1ae
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
62
bin/hyperion.init.sh
Normal 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
|
@ -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
|
||||||
|
21
cmake/FindCoreFoundation.cmake
Normal file
21
cmake/FindCoreFoundation.cmake
Normal 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
21
cmake/FindIOKit.cmake
Normal 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)
|
43
dependencies/build/hidapi/CMakeLists.txt
vendored
43
dependencies/build/hidapi/CMakeLists.txt
vendored
@ -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
1112
dependencies/build/hidapi/hid-mac.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
deploy/hyperion.deps.openelec-rpi.tar.gz.REMOVED.git-id
Normal file
1
deploy/hyperion.deps.openelec-rpi.tar.gz.REMOVED.git-id
Normal file
@ -0,0 +1 @@
|
|||||||
|
4d50c38a61c9f32a15b29ef3b3953c2835fa9cac
|
@ -1 +1 @@
|
|||||||
27dcc318ae9a9226676fb33626500e57703d7b6d
|
69287788649383ba7926e315debc69b7f4bd82a0
|
@ -57,7 +57,6 @@ target_link_libraries(hyperion
|
|||||||
hyperion-utils
|
hyperion-utils
|
||||||
leddevice
|
leddevice
|
||||||
effectengine
|
effectengine
|
||||||
hidapi-libusb
|
|
||||||
serialport
|
serialport
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
// STL includes
|
// STL includes
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// hyperion includes
|
// hyperion includes
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
|
130
libsrc/leddevice/LedDevicePiBlaster.cpp
Normal file
130
libsrc/leddevice/LedDevicePiBlaster.cpp
Normal 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;
|
||||||
|
}
|
59
libsrc/leddevice/LedDevicePiBlaster.h
Normal file
59
libsrc/leddevice/LedDevicePiBlaster.h
Normal 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;
|
||||||
|
};
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
1
src/config-tool/.gitignore
vendored
1
src/config-tool/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/.metadata
|
|
@ -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>
|
|
3
src/config-tool/ConfigTool/.gitignore
vendored
3
src/config-tool/ConfigTool/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
/.settings
|
|
||||||
/classes
|
|
||||||
/hyerpcon.dat
|
|
@ -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>
|
|
@ -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>
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 |
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
d37be0ef34a74fb15c9ec81e9ebadb57de62d294
|
|
@ -1 +0,0 @@
|
|||||||
1df18121f930623884da3de93f146f93d11f621c
|
|
@ -1 +0,0 @@
|
|||||||
97019f8cd170a7792bb81ae09efd690669eef567
|
|
@ -1 +0,0 @@
|
|||||||
b607e73b98996bfa40d19d508be01919552552d0
|
|
@ -1 +0,0 @@
|
|||||||
0d3aafb4a85649e53888a660b87de98f59f0ec32
|
|
@ -1 +0,0 @@
|
|||||||
7962c1194cb2a2b7af6c3b34151701e113f00087
|
|
Binary file not shown.
Before Width: | Height: | Size: 65 KiB |
@ -1 +0,0 @@
|
|||||||
ad1aba652ea186845d0c340cbeca7efb9d662e10
|
|
@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package org.hyperion.hypercon.spec;
|
|
||||||
|
|
||||||
public enum ColorByteOrder {
|
|
||||||
RGB, RBG, BRG, BGR, GRB, GBR
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
||||||
|
@ -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()
|
||||||
|
@ -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
138
test/TestNonInvWs2812b.cpp
Normal 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
20
test/TestQtScreenshot.cpp
Normal 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;
|
||||||
|
}
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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, ¶ms);
|
||||||
|
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, ¶ms);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user