initial commit
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# build packages
|
||||
for folder in *; do
|
||||
if [ -d $folder ] && [ ${folder:0:1} != "#" ]; then
|
||||
package="$(cat $folder/DEBIAN/control | grep 'Package: ')"
|
||||
arch="$(cat $folder/DEBIAN/control | grep 'Architecture: ')"
|
||||
version="$(cat $folder/DEBIAN/control | grep 'Version: ')"
|
||||
dpkg --build $folder "${package#*: }_${version#*: }_${arch#*: }.deb"
|
||||
#echo "${package#*: }_${version#*: }_${arch#*: }.deb"
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -fr /assets/packages/*.deb
|
||||
rm -fr /assets/packages/Packages*
|
||||
rm -fr /assets/packages/Release
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,39 @@
|
||||
Package: tooloop-gstreamer
|
||||
Maintainer: vollstock <daniel@vollstock.de>
|
||||
Homepage: https://www.vollstock.de
|
||||
Architecture: all
|
||||
Version: 1.8.3
|
||||
Section: tooloop/addon
|
||||
Depends: mpg123,
|
||||
libmpg123-dev,
|
||||
gstreamer1.0-doc,
|
||||
gstreamer1.0-tools,
|
||||
gstreamer1.0-alsa,
|
||||
gstreamer1.0-libav,
|
||||
gstreamer1.0-pulseaudio,
|
||||
gstreamer1.0-plugins-base,
|
||||
gstreamer1.0-plugins-base-doc,
|
||||
gstreamer1.0-plugins-base-dbg,
|
||||
gstreamer1.0-plugins-good,
|
||||
gstreamer1.0-plugins-good-doc,
|
||||
gstreamer1.0-plugins-good-dbg,
|
||||
gstreamer1.0-plugins-bad,
|
||||
gstreamer1.0-plugins-bad-doc,
|
||||
gstreamer1.0-plugins-bad-dbg,
|
||||
gstreamer1.0-plugins-ugly,
|
||||
gstreamer1.0-plugins-ugly-doc,
|
||||
gstreamer1.0-plugins-ugly-dbg,
|
||||
gstreamer1.0-vaapi,
|
||||
gstreamer1.0-vaapi-doc,
|
||||
gstreamer1.0-x,
|
||||
libgstreamer1.0-0,
|
||||
libgstreamer1.0-0-dbg,
|
||||
libgstreamer1.0-dev,
|
||||
va-driver-all,
|
||||
libva-glx1,
|
||||
libva-x11-1,
|
||||
vainfo
|
||||
Description: Gstreamer
|
||||
GStreamer is a library for constructing graphs of media-handling components.
|
||||
The applications it supports range from simple Ogg/Vorbis playback, audio/video
|
||||
streaming to complex audio (mixing) and video (non-linear editing) processing.
|
||||
@@ -0,0 +1,11 @@
|
||||
Package: tooloop-image-slideshow
|
||||
Version: 0.9.0
|
||||
Maintainer: vollstock <daniel@vollstock.de>
|
||||
Homepage: https://www.vollstock.de
|
||||
Bugs: https://github.com/vollstock/Tooloop-Examples
|
||||
Section: tooloop/presentation
|
||||
Architecture: all
|
||||
Depends: chromium-browser
|
||||
Description: Image slideshow
|
||||
A simple example app using the chromium browser and some javascript to display
|
||||
a fullscreen image slideshow.
|
||||
|
After Width: | Height: | Size: 899 KiB |
|
After Width: | Height: | Size: 281 KiB |
|
After Width: | Height: | Size: 535 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 466 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
After Width: | Height: | Size: 323 KiB |
|
After Width: | Height: | Size: 451 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 262 KiB |
|
After Width: | Height: | Size: 592 KiB |
@@ -0,0 +1,68 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Slideshow</title>
|
||||
<style media="screen">
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
div {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position:absolute;
|
||||
z-index:1;
|
||||
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
}
|
||||
div.active{
|
||||
z-index:3
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="slideshow">
|
||||
<div style="background-image: url(/assets/data/image1.jpg)" class="active"></div>
|
||||
<div style="background-image: url(/assets/data/image2.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image3.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image4.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image5.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image6.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image7.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image8.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image9.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image10.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image11.jpg)" ></div>
|
||||
<div style="background-image: url(/assets/data/image12.jpg)" ></div>
|
||||
</div>
|
||||
|
||||
<script type='application/javascript' src='jquery-3.1.1.min.js'></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
function nextImage() {
|
||||
var $active = $('#slideshow .active');
|
||||
var $next = ($active.next().length > 0) ? $active.next() : $('#slideshow div:first');
|
||||
|
||||
$next.css('z-index', 2); // move the next image up the pile
|
||||
|
||||
$active.fadeOut(500, function() { // fade out the top image
|
||||
$active.css('z-index',1).show().removeClass('active'); // reset the z-index and unhide the image
|
||||
$next.css('z-index',3).addClass('active'); // make the next image the top one
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
setInterval('nextImage()', 7000);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
COMMAND="chromium-browser --noerrdialogs --kiosk --incognito /assets/presentation/slideshow.html"
|
||||
|
||||
if [ $EUID == 0 ]; then
|
||||
su tooloop -c "$COMMAND" &
|
||||
else
|
||||
$COMMAND &
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
pkill chromium
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Image Slideshow",
|
||||
"description": "A browser base image slideshow.",
|
||||
"media": [],
|
||||
"version": "1.0",
|
||||
"last_updated": "2018-02-20",
|
||||
"license": "Public domain",
|
||||
"category": "Examples",
|
||||
"tags": ["example"],
|
||||
"developer": "vollstock",
|
||||
"homepage": "http://www.vollstock.de/",
|
||||
"compatibility": {
|
||||
"s": "True",
|
||||
"m": "True",
|
||||
"l": "True",
|
||||
"xl": "True"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,12 @@
|
||||
Package: tooloop-kiosk-browser
|
||||
Version: 0.9.0
|
||||
Maintainer: vollstock
|
||||
Homepage: https://www.vollstock.de
|
||||
Bugs: https://github.com/vollstock/Tooloop-Examples.git
|
||||
Section: tooloop/presentation
|
||||
Architecture: amd64
|
||||
Depends: chromium-browser
|
||||
Recommends: tooloop-transparent-cursor
|
||||
Description: Kiosk Browser
|
||||
A simple fullscreen kiosk browser based using chromium.
|
||||
You can define its’ homepage in the settings.
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status
|
||||
set -e
|
||||
# Restart the settings server
|
||||
systemctl restart tooloop-settings-server
|
||||
# Exit cleanly
|
||||
exit 0
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status
|
||||
set -e
|
||||
# Restart the settings server
|
||||
systemctl restart tooloop-settings-server
|
||||
# Exit cleanly
|
||||
exit 0
|
||||
@@ -0,0 +1,217 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Simple Kiosk</title>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
#particles {
|
||||
position:absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #172e4d;
|
||||
/*background: radial-gradient(ellipse at center, #224a5e 0%,#172e4d 100%);*/
|
||||
background: radial-gradient(ellipse at center, #224a5e 0%,#172e4d 50%,#050b23 100%);
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
|
||||
#box {
|
||||
width: 50%;
|
||||
position: absolute;
|
||||
background: rgba(255,255,255,0.9);
|
||||
left: 25%;
|
||||
top: 25%;
|
||||
border-radius: 2px;
|
||||
padding: 20px;
|
||||
max-width: 640px;
|
||||
box-sizing: border-box;
|
||||
padding: 50px 40px 50px 40px;
|
||||
-webkit-user-select: none; /* Chrome all / Safari all */
|
||||
-moz-user-select: none; /* Firefox all */
|
||||
-ms-user-select: none; /* IE 10+ */
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#credits {
|
||||
color: white;
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
font-size: 10px;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
body, div, h1, p {
|
||||
margin: 0;
|
||||
font-family: 'ClearSans', sans-serif;
|
||||
font-weight: 100;
|
||||
font-size: 18px;
|
||||
line-height: 1.25em;
|
||||
}
|
||||
|
||||
h1, p {
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: lighter;
|
||||
color: #b1148e;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
a, a:visited, a:active {
|
||||
color: #b1148e;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="particles"></div>
|
||||
|
||||
<div id="box">
|
||||
<h1>Simple Kiosk</h1>
|
||||
<p>This is a simple browser for your show room or trade fair booth.</p>
|
||||
<p>It has very few features but works for simple things.</p>
|
||||
<p>By default it loads <span style="font-family: monospace;">/assets/data/index.html</span> but you can choose any page you like.</p>
|
||||
<p>Simple Kiosk comes with a plugin for the Tooloop Settings Server so you can configure it in there.</p>
|
||||
</div>
|
||||
|
||||
<div id="credits"><a href="http://vincentgarreau.com/particles.js/">particles.js</a> by Vincent Garreau</div>
|
||||
|
||||
<!-- particles.js lib - https://github.com/VincentGarreau/particles.js -->
|
||||
<script src="particles.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
particlesJS("particles", {
|
||||
"particles": {
|
||||
"number": {
|
||||
"value": 100,
|
||||
"density": {
|
||||
"enable": true,
|
||||
"value_area": 1000
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"value": "#ffffff"
|
||||
},
|
||||
"shape": {
|
||||
"type": "polygon",
|
||||
"stroke": {
|
||||
"width": 0,
|
||||
"color": "#000000"
|
||||
},
|
||||
"polygon": {
|
||||
"nb_sides": 8
|
||||
},
|
||||
// "image": {
|
||||
// "src": "img/github.svg",
|
||||
// "width": 100,
|
||||
// "height": 100
|
||||
// }
|
||||
},
|
||||
"opacity": {
|
||||
"value": 0.5,
|
||||
"random": false,
|
||||
"anim": {
|
||||
"enable": false,
|
||||
"speed": 1,
|
||||
"opacity_min": 0.1,
|
||||
"sync": false
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"value": 2,
|
||||
"random": true,
|
||||
"anim": {
|
||||
"enable": false,
|
||||
"speed": 40,
|
||||
"size_min": 0.1,
|
||||
"sync": false
|
||||
}
|
||||
},
|
||||
"line_linked": {
|
||||
"enable": true,
|
||||
"distance": 150,
|
||||
"color": "#ffffff",
|
||||
"opacity": 0.4,
|
||||
"width": 1.5
|
||||
},
|
||||
"move": {
|
||||
"enable": true,
|
||||
"speed": 3,
|
||||
"direction": "none",
|
||||
"random": true,
|
||||
"straight": false,
|
||||
"out_mode": "out",
|
||||
"bounce": false,
|
||||
"attract": {
|
||||
"enable": true,
|
||||
"rotateX": 600,
|
||||
"rotateY": 1200
|
||||
}
|
||||
}
|
||||
},
|
||||
"interactivity": {
|
||||
"detect_on": "window",
|
||||
"events": {
|
||||
"onhover": {
|
||||
"enable": false,
|
||||
"mode": "repulse"
|
||||
},
|
||||
"onclick": {
|
||||
"enable": true,
|
||||
"mode": "push"
|
||||
},
|
||||
"resize": true
|
||||
},
|
||||
"modes": {
|
||||
"grab": {
|
||||
"distance": 400,
|
||||
"line_linked": {
|
||||
"opacity": 1
|
||||
}
|
||||
},
|
||||
"bubble": {
|
||||
"distance": 400,
|
||||
"size": 40,
|
||||
"duration": 2,
|
||||
"opacity": 8,
|
||||
"speed": 3
|
||||
},
|
||||
"repulse": {
|
||||
"distance": 200,
|
||||
"duration": 0.4
|
||||
},
|
||||
"push": {
|
||||
"particles_nb": 3
|
||||
},
|
||||
"remove": {
|
||||
"particles_nb": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"retina_detect": true
|
||||
});
|
||||
var update = function() {
|
||||
requestAnimationFrame(update);
|
||||
};
|
||||
requestAnimationFrame(update);;
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
URL="file:///assets/data/index.html"
|
||||
|
||||
# List of Chromium Command Line Switches
|
||||
# https://peter.sh/experiments/chromium-command-line-switches/
|
||||
COMMAND="chromium-browser \
|
||||
--kiosk \
|
||||
--bwsi \
|
||||
--overscroll-history-navigation=1 \
|
||||
--incognito \
|
||||
--disable-infobars \
|
||||
--disable-translate \
|
||||
--no-default-browser-check \
|
||||
--no-first-run \
|
||||
--disable-translate-new-ux \
|
||||
--num-raster-threads=4 \
|
||||
--enable-zero-copy \
|
||||
--noerrdialogs \
|
||||
--class=TooloopKiosk \
|
||||
$URL"
|
||||
|
||||
if [ $EUID == 0 ]; then
|
||||
pkill chromium
|
||||
sleep 0.1
|
||||
su tooloop -c "$COMMAND" &
|
||||
else
|
||||
pkill chromium
|
||||
sleep 0.1
|
||||
$COMMAND &
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
IDLETIME=60
|
||||
RESET_COMMAND="/bin/bash /assets/presentation/reset-kiosk.sh"
|
||||
|
||||
$RESET_COMMAND
|
||||
xidlerun -t $IDLETIME -c "$RESET_COMMAND" &
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
pkill xidlerun &
|
||||
pkill chromium &
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Simple Kiosk",
|
||||
"description": "A simple kiosk browser based using chromium.",
|
||||
"media": [],
|
||||
"version": "1.0",
|
||||
"last_updated": "2017-12-21",
|
||||
"license": "Public domain",
|
||||
"category": "Examples",
|
||||
"tags": ["example"],
|
||||
"developer": "vollstock",
|
||||
"homepage": "http://www.vollstock.de/",
|
||||
"compatibility": {
|
||||
"s": "True",
|
||||
"m": "True",
|
||||
"l": "True",
|
||||
"xl": "True"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from flask import Flask, jsonify, request, abort
|
||||
from os import chown
|
||||
from pwd import getpwnam
|
||||
from grp import getgrnam
|
||||
|
||||
class InstalledApp(object):
|
||||
|
||||
def __init__(self, flask):
|
||||
super(InstalledApp, self).__init__()
|
||||
|
||||
# default homepage
|
||||
self.homepage = 'file:///assets/data/index.html';
|
||||
|
||||
# connect flask routes to tooloop api calls
|
||||
self.add_routes(flask)
|
||||
|
||||
|
||||
|
||||
def add_routes(self, flask):
|
||||
|
||||
@flask.route('/simple-kiosk/change-homepage', methods=['POST'])
|
||||
def change_homepage():
|
||||
if not request.form or not 'homepage' in request.form:
|
||||
abort(400)
|
||||
|
||||
try:
|
||||
self.homepage = request.form['homepage'];
|
||||
|
||||
file = open('/assets/presentation/reset-kiosk.sh','w')
|
||||
|
||||
file.write('#!/bin/bash\n')
|
||||
file.write('\n')
|
||||
file.write('URL="'+self.homepage+'"\n')
|
||||
file.write('\n')
|
||||
file.write('# List of Chromium Command Line Switches\n')
|
||||
file.write('# https://peter.sh/experiments/chromium-command-line-switches/\n')
|
||||
file.write('COMMAND="chromium-browser \\\n')
|
||||
file.write('--kiosk \\\n')
|
||||
file.write('--bwsi \\\n')
|
||||
file.write('--overscroll-history-navigation=1 \\\n')
|
||||
file.write('--incognito \\\n')
|
||||
file.write('--disable-infobars \\\n')
|
||||
file.write('--disable-translate \\\n')
|
||||
file.write('--no-default-browser-check \\\n')
|
||||
file.write('--no-first-run \\\n')
|
||||
file.write('--disable-translate-new-ux \\\n')
|
||||
file.write('--num-raster-threads=4 \\\n')
|
||||
file.write('--enable-zero-copy \\\n')
|
||||
file.write('--noerrdialogs \\\n')
|
||||
file.write('--class=TooloopKiosk \\\n')
|
||||
file.write('$URL"\n')
|
||||
file.write('\n')
|
||||
file.write('if [ $EUID == 0 ]; then\n')
|
||||
file.write(' pkill chromium\n')
|
||||
file.write(' sleep 0.1\n')
|
||||
file.write(' su tooloop -c "$COMMAND" &\n')
|
||||
file.write('else\n')
|
||||
file.write(' pkill chromium\n')
|
||||
file.write(' sleep 0.1\n')
|
||||
file.write(' $COMMAND &\n')
|
||||
file.write('fi\n')
|
||||
file.write('\n')
|
||||
file.write('exit 0\n')
|
||||
|
||||
file.close()
|
||||
|
||||
uid = getpwnam('tooloop').pw_uid
|
||||
gid = getgrnam('tooloop').gr_gid
|
||||
chown('/assets/presentation/reset-kiosk.sh', uid, gid)
|
||||
|
||||
return jsonify({'message':'homepage changed'})
|
||||
|
||||
except Exception as e:
|
||||
abort(500)
|
||||
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,43 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<table class="settings-table">
|
||||
<tr><td colspan="2"><h2>{{installed_app.name}}</h2></td></tr>
|
||||
|
||||
<tr>
|
||||
<td class="label-column" style="vertical-align: top; padding-top: 1.1em;">Homepage</td>
|
||||
<td class="value-column">
|
||||
<form id="homepage-form">
|
||||
<input type="text" id="homepage-input" value="{{app_controller.homepage}}">
|
||||
<button type="submit">Save</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block page_footer_scripts %}
|
||||
<script type="text/javascript">
|
||||
|
||||
$('#homepage-form').on('submit', function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var feedback = attachFeedback(event.target);
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
data: { "homepage":$('#homepage-input').val() },
|
||||
url: "/simple-kiosk/change-homepage"
|
||||
}).done(function( data ) {
|
||||
displayConfirmFeedback(feedback, 'Saved');
|
||||
$.ajax( {url:"/tooloop/api/v1.0/presentation/reset"} );
|
||||
}).error(function( jqXHR, textStatus, errorThrown ) {
|
||||
displayErrorFeedback(feedback, errorThrown);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,11 @@
|
||||
Package: tooloop-processing-example
|
||||
Version: 0.9.0
|
||||
Maintainer: vollstock <daniel@vollstock.de>
|
||||
Homepage: https://www.vollstock.de
|
||||
Architecture: all
|
||||
Section: tooloop/presentation
|
||||
Pre-Depends: tooloop-processing (= 3.4.0)
|
||||
Description: Processing Example
|
||||
This is a just a simple example of how to bundle processing sketches
|
||||
in a .deb bundle that runs on Tooloop OS.
|
||||
**Flocking** by Daniel Shiffman. https://processing.org/examples/flocking.html
|
||||
@@ -0,0 +1,249 @@
|
||||
Flock flock;
|
||||
|
||||
void setup() {
|
||||
fullScreen();
|
||||
//size(640, 480);
|
||||
flock = new Flock();
|
||||
// Add an initial set of boids into the system
|
||||
for (int i = 0; i < 150; i++) {
|
||||
flock.addBoid(new Boid(width/2,height/2));
|
||||
}
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(50);
|
||||
flock.run();
|
||||
}
|
||||
|
||||
// Add a new boid into the System
|
||||
void mousePressed() {
|
||||
flock.addBoid(new Boid(mouseX,mouseY));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// The Flock (a list of Boid objects)
|
||||
|
||||
class Flock {
|
||||
ArrayList<Boid> boids; // An ArrayList for all the boids
|
||||
|
||||
Flock() {
|
||||
boids = new ArrayList<Boid>(); // Initialize the ArrayList
|
||||
}
|
||||
|
||||
void run() {
|
||||
for (Boid b : boids) {
|
||||
b.run(boids); // Passing the entire list of boids to each boid individually
|
||||
}
|
||||
}
|
||||
|
||||
void addBoid(Boid b) {
|
||||
boids.add(b);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// The Boid class
|
||||
|
||||
class Boid {
|
||||
|
||||
PVector position;
|
||||
PVector velocity;
|
||||
PVector acceleration;
|
||||
float r;
|
||||
float maxforce; // Maximum steering force
|
||||
float maxspeed; // Maximum speed
|
||||
|
||||
Boid(float x, float y) {
|
||||
acceleration = new PVector(0, 0);
|
||||
|
||||
// This is a new PVector method not yet implemented in JS
|
||||
// velocity = PVector.random2D();
|
||||
|
||||
// Leaving the code temporarily this way so that this example runs in JS
|
||||
float angle = random(TWO_PI);
|
||||
velocity = new PVector(cos(angle), sin(angle));
|
||||
|
||||
position = new PVector(x, y);
|
||||
r = 2.0;
|
||||
maxspeed = 2;
|
||||
maxforce = 0.03;
|
||||
}
|
||||
|
||||
void run(ArrayList<Boid> boids) {
|
||||
flock(boids);
|
||||
update();
|
||||
borders();
|
||||
render();
|
||||
}
|
||||
|
||||
void applyForce(PVector force) {
|
||||
// We could add mass here if we want A = F / M
|
||||
acceleration.add(force);
|
||||
}
|
||||
|
||||
// We accumulate a new acceleration each time based on three rules
|
||||
void flock(ArrayList<Boid> boids) {
|
||||
PVector sep = separate(boids); // Separation
|
||||
PVector ali = align(boids); // Alignment
|
||||
PVector coh = cohesion(boids); // Cohesion
|
||||
// Arbitrarily weight these forces
|
||||
sep.mult(1.5);
|
||||
ali.mult(1.0);
|
||||
coh.mult(1.0);
|
||||
// Add the force vectors to acceleration
|
||||
applyForce(sep);
|
||||
applyForce(ali);
|
||||
applyForce(coh);
|
||||
}
|
||||
|
||||
// Method to update position
|
||||
void update() {
|
||||
// Update velocity
|
||||
velocity.add(acceleration);
|
||||
// Limit speed
|
||||
velocity.limit(maxspeed);
|
||||
position.add(velocity);
|
||||
// Reset accelertion to 0 each cycle
|
||||
acceleration.mult(0);
|
||||
}
|
||||
|
||||
// A method that calculates and applies a steering force towards a target
|
||||
// STEER = DESIRED MINUS VELOCITY
|
||||
PVector seek(PVector target) {
|
||||
PVector desired = PVector.sub(target, position); // A vector pointing from the position to the target
|
||||
// Scale to maximum speed
|
||||
desired.normalize();
|
||||
desired.mult(maxspeed);
|
||||
|
||||
// Above two lines of code below could be condensed with new PVector setMag() method
|
||||
// Not using this method until Processing.js catches up
|
||||
// desired.setMag(maxspeed);
|
||||
|
||||
// Steering = Desired minus Velocity
|
||||
PVector steer = PVector.sub(desired, velocity);
|
||||
steer.limit(maxforce); // Limit to maximum steering force
|
||||
return steer;
|
||||
}
|
||||
|
||||
void render() {
|
||||
// Draw a triangle rotated in the direction of velocity
|
||||
float theta = velocity.heading2D() + radians(90);
|
||||
// heading2D() above is now heading() but leaving old syntax until Processing.js catches up
|
||||
|
||||
fill(200, 100);
|
||||
stroke(255);
|
||||
pushMatrix();
|
||||
translate(position.x, position.y);
|
||||
rotate(theta);
|
||||
beginShape(TRIANGLES);
|
||||
vertex(0, -r*2);
|
||||
vertex(-r, r*2);
|
||||
vertex(r, r*2);
|
||||
endShape();
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
// Wraparound
|
||||
void borders() {
|
||||
if (position.x < -r) position.x = width+r;
|
||||
if (position.y < -r) position.y = height+r;
|
||||
if (position.x > width+r) position.x = -r;
|
||||
if (position.y > height+r) position.y = -r;
|
||||
}
|
||||
|
||||
// Separation
|
||||
// Method checks for nearby boids and steers away
|
||||
PVector separate (ArrayList<Boid> boids) {
|
||||
float desiredseparation = 25.0f;
|
||||
PVector steer = new PVector(0, 0, 0);
|
||||
int count = 0;
|
||||
// For every boid in the system, check if it's too close
|
||||
for (Boid other : boids) {
|
||||
float d = PVector.dist(position, other.position);
|
||||
// If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
|
||||
if ((d > 0) && (d < desiredseparation)) {
|
||||
// Calculate vector pointing away from neighbor
|
||||
PVector diff = PVector.sub(position, other.position);
|
||||
diff.normalize();
|
||||
diff.div(d); // Weight by distance
|
||||
steer.add(diff);
|
||||
count++; // Keep track of how many
|
||||
}
|
||||
}
|
||||
// Average -- divide by how many
|
||||
if (count > 0) {
|
||||
steer.div((float)count);
|
||||
}
|
||||
|
||||
// As long as the vector is greater than 0
|
||||
if (steer.mag() > 0) {
|
||||
// First two lines of code below could be condensed with new PVector setMag() method
|
||||
// Not using this method until Processing.js catches up
|
||||
// steer.setMag(maxspeed);
|
||||
|
||||
// Implement Reynolds: Steering = Desired - Velocity
|
||||
steer.normalize();
|
||||
steer.mult(maxspeed);
|
||||
steer.sub(velocity);
|
||||
steer.limit(maxforce);
|
||||
}
|
||||
return steer;
|
||||
}
|
||||
|
||||
// Alignment
|
||||
// For every nearby boid in the system, calculate the average velocity
|
||||
PVector align (ArrayList<Boid> boids) {
|
||||
float neighbordist = 50;
|
||||
PVector sum = new PVector(0, 0);
|
||||
int count = 0;
|
||||
for (Boid other : boids) {
|
||||
float d = PVector.dist(position, other.position);
|
||||
if ((d > 0) && (d < neighbordist)) {
|
||||
sum.add(other.velocity);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
sum.div((float)count);
|
||||
// First two lines of code below could be condensed with new PVector setMag() method
|
||||
// Not using this method until Processing.js catches up
|
||||
// sum.setMag(maxspeed);
|
||||
|
||||
// Implement Reynolds: Steering = Desired - Velocity
|
||||
sum.normalize();
|
||||
sum.mult(maxspeed);
|
||||
PVector steer = PVector.sub(sum, velocity);
|
||||
steer.limit(maxforce);
|
||||
return steer;
|
||||
}
|
||||
else {
|
||||
return new PVector(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Cohesion
|
||||
// For the average position (i.e. center) of all nearby boids, calculate steering vector towards that position
|
||||
PVector cohesion (ArrayList<Boid> boids) {
|
||||
float neighbordist = 50;
|
||||
PVector sum = new PVector(0, 0); // Start with empty vector to accumulate all positions
|
||||
int count = 0;
|
||||
for (Boid other : boids) {
|
||||
float d = PVector.dist(position, other.position);
|
||||
if ((d > 0) && (d < neighbordist)) {
|
||||
sum.add(other.position); // Add position
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
sum.div(count);
|
||||
return seek(sum); // Steer towards the position
|
||||
}
|
||||
else {
|
||||
return new PVector(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
/assets/addons/processing-3.4.0/processing-java --sketch=/assets/presentation/Flocking --present &
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
pkill java
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,10 @@
|
||||
Package: tooloop-transparent-cursor
|
||||
Version: 0.9.0
|
||||
Maintainer: vollstock
|
||||
Homepage: https://www.vollstock.de
|
||||
Bugs: https://github.com/vollstock/xcursor-transparent-cursor
|
||||
Section: tooloop/addon
|
||||
Architecture: all
|
||||
Description: Transparent mouse cursor
|
||||
Install it if you want to hide the mouse cursor completely
|
||||
e. g. on touch displays.
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status.
|
||||
set -e
|
||||
# restart openbox for immediate effect
|
||||
openbox --restart
|
||||
# Exit cleanly
|
||||
exit 0
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status.
|
||||
set -e
|
||||
# restart openbox for immediate effect
|
||||
openbox --restart
|
||||
# Exit cleanly
|
||||
exit 0
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# move them to the repository
|
||||
mv *.deb /assets/packages
|
||||
|
||||
# update apt
|
||||
/opt/tooloop/scripts/tooloop-update-packages
|
||||
|
||||
#echo " "
|
||||
#echo "Available packages:"
|
||||
apt list tooloop*
|
||||
@@ -0,0 +1,10 @@
|
||||
Package: tooloop-video-player
|
||||
Version: 0.9.0
|
||||
Maintainer: vollstock
|
||||
Homepage: https://www.vollstock.de
|
||||
Bugs: https://github.com/vollstock/Tooloop-Examples
|
||||
Section: tooloop/presentation
|
||||
Architecture: all
|
||||
Depends: mplayer
|
||||
Description: Video Player
|
||||
The tooloop video player is using mplayer to loop over all videos it find in `/assets/data`.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Super simpler video player
|
||||
|
||||
The super simple video player is an example of how to use the Tooloop media
|
||||
server and provide apps for it.
|
||||
|
||||
It's in the public domain.
|
||||
|
||||
|
||||
# MPlayer
|
||||
|
||||
[MPlayer](http://www.mplayerhq.hu) is available under the [GNU General Public
|
||||
License version 2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
|
||||
It is not available under any other licensing terms, not even for substantial
|
||||
amounts of money. If you have questions about the GNU GPL, consult the GPL FAQ.
|
||||
@@ -0,0 +1,7 @@
|
||||
# Super simple video player
|
||||
|
||||
In this example we are using [mplayer](http://mplayerhq.hu) to play and loop a list of videos in fullscreen.
|
||||
|
||||
## Customizing
|
||||
|
||||
Check out the start script if you want to fiddle with some mplayer options. [Here's the docs](http://www.mplayerhq.hu/design7/documentation.html).
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
mplayer -fs -zoom /assets/data/Tooloop\ Greeter\ Intro.mp4 /assets/data/Tooloop\ Greeter\ Loop.mp4 -loop 0 &
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# here comes everything, you need to stop the running presentation
|
||||
# basically kill or stop everything you started in `start-presentation.sh`
|
||||
|
||||
kill $(pidof mplayer)
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Simple Video Player",
|
||||
"description": "Uses [mplayer](http://mplayerhq.hu) to play and loop a list of videos in fullscreen.",
|
||||
"media": [],
|
||||
"version": "1.0",
|
||||
"last_updated": "2018-02-13",
|
||||
"license": "Public domain",
|
||||
"category": "Examples",
|
||||
"tags": ["example"],
|
||||
"developer": "vollstock",
|
||||
"homepage": "http://www.vollstock.de/",
|
||||
"compatibility": {
|
||||
"s": "False",
|
||||
"m": "True",
|
||||
"l": "True",
|
||||
"xl": "True"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
apt update
|
||||
apt -y install mplayer
|
||||
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# remove all files we have copied to data folder
|
||||
rm /assets/data/tooloop-greeter*
|
||||
|
||||
# we have installed it, we should remove it also
|
||||
apt -y purge mplayer
|
||||