Merge pull request #916 from ostcar/projector

Send js to the projector
This commit is contained in:
Oskar Hahn 2013-10-21 05:05:40 -07:00
commit 9682a48da2
14 changed files with 193 additions and 140 deletions

View File

@ -5,6 +5,8 @@
<hr>
</h1>
{% if item.text %}
{{ item.text|safe|linebreaks }}
{% endif %}
<div class="scroll">
{% if item.text %}
{{ item.text|safe|linebreaks }}
{% endif %}
</div>

View File

@ -21,7 +21,7 @@
{% if item.speaker_list_closed %}(<span class="closed">{% trans 'closed' %}</span>){% endif %}
</h3>
<p>
<div class="scroll">
{% if list_of_speakers %}
<ul id="list_of_speakers">
{% for speaker_dict in list_of_speakers %}
@ -36,5 +36,5 @@
{% else %}
<i>{% trans 'The list of speakers is empty.' %}</i>
{% endif %}
</p>
</div>

View File

@ -19,92 +19,94 @@
</small>
<hr>
</h1>
{% if not assignment.candidates %}
<p>
<div class="text">{{ assignment.description|linebreaks }}</div>
</p>
{% endif %}
<div class="scroll">
{% if not assignment.candidates %}
<p>
<div class="text">{{ assignment.description|linebreaks }}</div>
</p>
{% endif %}
{% if assignment.candidates and assignment.status != "fin" %}
<h3>{% trans "Candidates" %}</h3>
<ol>
{% for candidate in assignment.candidates %}
<li>{{ candidate }} </li>
{% empty %}
<li style="list-style: none outside none;">
<i>{% trans "No candidates available." %}</i>
</li>
{% endfor %}
</ol>
<p><br></p>
{% endif %}
{% if assignment.candidates and assignment.status != "fin" %}
<h3>{% trans "Candidates" %}</h3>
<ol>
{% for candidate in assignment.candidates %}
<li>{{ candidate }} </li>
{% empty %}
<li style="list-style: none outside none;">
<i>{% trans "No candidates available." %}</i>
</li>
{% endfor %}
</ol>
<p><br></p>
{% endif %}
{% if polls.exists %}
<h3>{% trans "Election results" %}</h3>
<table class="table-striped table-bordered">
<tr>
<th>{% trans "Candidates" %}</th>
{% for poll in polls %}
<th>
<nobr>{{ poll.get_ballot }}. {% trans "ballot" %}</nobr>
</th>
{% endfor %}
</tr>
{% for candidate, poll_list in vote_results.items %}
{% if polls.exists %}
<h3>{% trans "Election results" %}</h3>
<table class="table-striped table-bordered">
<tr>
<td class="{% if candidate in assignment.elected %} elected{% endif %}">
{% if candidate in assignment.elected %}
<a class="elected">
<img src="{% static 'img/voting-yes.png' %}" title="{% trans 'Candidate is elected' %}">
</a>
{% endif %}
{{ candidate }}
</td>
{% for vote in poll_list %}
<td style="white-space:nowrap;"{% if candidate in assignment.elected %} class="elected"{% endif %}>
{% if not "assignment_publish_winner_results_only"|get_config or candidate in assignment.elected %}
{% if 'Yes' in vote and 'No' in vote and 'Abstain' in vote %}
<img src="{% static 'img/voting-yes.png' %}" title="{% trans 'Yes' %}"> {{ vote.Yes }}<br>
<img src="{% static 'img/voting-no.png' %}" title="{% trans 'No' %}"> {{ vote.No }}<br>
<img src="{% static 'img/voting-abstention.png' %}" title="{% trans 'Abstention' %}"> {{ vote.Abstain }}<br>
{% elif 'Votes' in vote %}
<img src="{% static 'img/voting-yes.png' %}" title="{% trans 'Yes' %}"> {{ vote.Votes }}
{% elif vote == None %}
{% trans 'was not a <br> candidate'%}
<th>{% trans "Candidates" %}</th>
{% for poll in polls %}
<th>
<nobr>{{ poll.get_ballot }}. {% trans "ballot" %}</nobr>
</th>
{% endfor %}
</tr>
{% for candidate, poll_list in vote_results.items %}
<tr>
<td class="{% if candidate in assignment.elected %} elected{% endif %}">
{% if candidate in assignment.elected %}
<a class="elected">
<img src="{% static 'img/voting-yes.png' %}" title="{% trans 'Candidate is elected' %}">
</a>
{% endif %}
{{ candidate }}
</td>
{% for vote in poll_list %}
<td style="white-space:nowrap;"{% if candidate in assignment.elected %} class="elected"{% endif %}>
{% if not "assignment_publish_winner_results_only"|get_config or candidate in assignment.elected %}
{% if 'Yes' in vote and 'No' in vote and 'Abstain' in vote %}
<img src="{% static 'img/voting-yes.png' %}" title="{% trans 'Yes' %}"> {{ vote.Yes }}<br>
<img src="{% static 'img/voting-no.png' %}" title="{% trans 'No' %}"> {{ vote.No }}<br>
<img src="{% static 'img/voting-abstention.png' %}" title="{% trans 'Abstention' %}"> {{ vote.Abstain }}<br>
{% elif 'Votes' in vote %}
<img src="{% static 'img/voting-yes.png' %}" title="{% trans 'Yes' %}"> {{ vote.Votes }}
{% elif vote == None %}
{% trans 'was not a <br> candidate'%}
{% else %}
&nbsp;
{% endif %}
{% else %}
&nbsp;
{% endif %}
{% else %}
&nbsp;
{% endif %}
</td>
</td>
{% endfor %}
</tr>
{% endfor %}
</tr>
{% endfor %}
<tr>
<td>{% trans 'Invalid votes' %}</td>
{% for poll in polls %}
<td style="white-space:nowrap;">
{% if poll.has_votes %}
<img src="{% static 'img/voting-invalid.png' %}" title="{% trans 'Invalid' %}">
{{ poll.print_votesinvalid }}
{% endif %}
</td>
<tr>
<td>{% trans 'Invalid votes' %}</td>
{% for poll in polls %}
<td style="white-space:nowrap;">
{% if poll.has_votes %}
<img src="{% static 'img/voting-invalid.png' %}" title="{% trans 'Invalid' %}">
{{ poll.print_votesinvalid }}
{% endif %}
</td>
{% endfor %}
</tr>
<tr class="total">
<td>
<strong>{% trans 'Votes cast' %}</strong>
</td>
{% for poll in polls %}
<td style="white-space:nowrap;">
{% if poll.has_votes %}
<img src="{% static 'img/voting-total.png' %}" title="{% trans 'Votes cast' %}">
<strong>{{ poll.print_votescast }}</strong>
{% endif %}
{% endfor %}
</tr>
<tr class="total">
<td>
<strong>{% trans 'Votes cast' %}</strong>
</td>
{% endfor %}
</tr>
</table>
{% endif %}
{% for poll in polls %}
<td style="white-space:nowrap;">
{% if poll.has_votes %}
<img src="{% static 'img/voting-total.png' %}" title="{% trans 'Votes cast' %}">
<strong>{{ poll.print_votescast }}</strong>
{% endif %}
</td>
{% endfor %}
</tr>
</table>
{% endif %}
</div>

View File

@ -61,11 +61,11 @@
<hr>
</h1>
<p>
<div class="scroll">
<div class="text">{{ motion.active_version.text|safe }}</div>
{% if motion.active_version.reason %}
<br>
<div class="reason"><p><b>{% trans "Reason" %}:</b></p>
{{ motion.active_version.reason|safe }}</div>
{% endif %}
</p>
</div>

View File

@ -65,6 +65,16 @@ def update_projector_overlay(overlay):
ProjectorSocketHandler.send_updates({'overlays': overlay_dict})
def call_on_projector(calls):
"""
Sends data to the projector.
"""
projector_js_cache = config['projector_js_cache']
projector_js_cache.update(calls)
config['projector_js_cache'] = projector_js_cache
ProjectorSocketHandler.send_updates(json.dumps({'calls': calls}))
def get_projector_content(slide_dict=None):
"""
Returns the HTML-Content block of the projector.

View File

@ -55,14 +55,18 @@ def config_variables(sender, **kwargs):
name='countdown_state',
default_value='inactive')
bigger = ConfigVariable(
name='bigger',
projector_scale = ConfigVariable(
name='projector_scale',
default_value=100)
projector_up = ConfigVariable(
name='up',
projector_scroll = ConfigVariable(
name='projector_scroll',
default_value=0)
projector_js_cache = ConfigVariable(
name='projector_js_cache',
default_value={})
projector_active_overlays = ConfigVariable(
name='projector_active_overlays',
default_value=[])
@ -71,7 +75,8 @@ def config_variables(sender, **kwargs):
title='No title here', url='bar', required_permission=None, variables=(
projector, projector_message,
countdown_time, countdown_start_stamp, countdown_pause_stamp,
countdown_state, bigger, projector_up, projector_active_overlays))
countdown_state, projector_scale, projector_scroll,
projector_active_overlays, projector_js_cache))
@receiver(projector_overlays, dispatch_uid="projector_countdown")

View File

@ -6,6 +6,7 @@
*/
$(document).ready(function() {
$('#content .scroll').wrap('<div class="scrollwrapper"></div>');
if ($('#content.reload').length > 0) {
updater.start();
}
@ -23,8 +24,17 @@ var projector = {
}
},
scroll: function(value) {
$('#content .scroll').css('margin-top', value + 'em')
},
scale: function(value) {
$('#content').css('font-size', value + '%');
$('#content #sidebar').css('font-size', '18px');
},
update_data: function(data) {
$.each(data, function (key, value) {
$.each(data, function (key, value) {
if (key === 'load_file')
projector.load_file(value);
else
@ -48,20 +58,29 @@ var updater = {
},
updateProjector: function(data) {
$('#content').html(data.content);
var overlays = data.overlays;
$.each(overlays, function (key, value) {
var overlay = $('#overlays #overlay_' + key)
if (!value)
overlay.remove();
else {
if (overlay.length) {
overlay.html(value.html)
} else {
$('#overlays').append(value.html);
if (data.content) {
$('#content').html(data.content);
$('#content .scroll').wrap('<div class="scrollwrapper"></div>');
}
if (data.overlays) {
$.each(data.overlays, function (key, value) {
var overlay = $('#overlays #overlay_' + key)
if (!value)
overlay.remove();
else {
if (overlay.length) {
overlay.html(value.html)
} else {
$('#overlays').append(value.html);
}
projector.update_data(value.javascript);
}
projector.update_data(value.javascript);
}
});
});
}
if (data.calls) {
$.each(data.calls, function (call, argument) {
projector[call](argument);
});
}
}
};

View File

@ -86,6 +86,13 @@ body{
top: 150px;
right: 40px;
z-index: -1;
transition: all 2s;
}
#content .scroll {
transition: margin 2s;
}
#content .scrollwrapper {
overflow: hidden;
}
h1 {
font-size: 45px !important;

View File

@ -40,6 +40,9 @@
{% for js in overlay_js %}
projector.update_data({{ js|safe }});
{% endfor %}
{% for key, value in calls.items %}
projector.{{ key }}({{ value }});
{% endfor %}
</script>
</body>
</html>

View File

@ -0,0 +1,9 @@
{% load i18n %}
<h1>{{ slide.title }}</h1>
<div class="scroll">
{% if slide.text %}
<span>{{ slide.text|safe|linebreaks }}</span>
{% endif %}
</div>

View File

@ -1,7 +0,0 @@
{% load i18n %}
<h1>{{ slide.title }}</h1>
{% if slide.text %}
<span>{{ slide.text|safe|linebreaks }}</span>
{% endif %}

View File

@ -58,47 +58,47 @@ urlpatterns = patterns(
name='customslide_delete'),
url(r'^bigger/$',
views.ProjectorEdit.as_view(),
views.ProjectorControllView.as_view(),
{'direction': 'bigger'},
name='projector_bigger'),
url(r'^smaller/$',
views.ProjectorEdit.as_view(),
views.ProjectorControllView.as_view(),
{'direction': 'smaller'},
name='projector_smaller'),
url(r'^up/$',
views.ProjectorEdit.as_view(),
views.ProjectorControllView.as_view(),
{'direction': 'up'},
name='projector_up'),
url(r'^down/$',
views.ProjectorEdit.as_view(),
views.ProjectorControllView.as_view(),
{'direction': 'down'},
name='projector_down'),
url(r'^clean/$',
views.ProjectorEdit.as_view(),
views.ProjectorControllView.as_view(),
{'direction': 'clean'},
name='projector_clean'),
url(r'^countdown/reset/$',
views.CountdownEdit.as_view(),
views.CountdownControllView.as_view(),
{'command': 'reset'},
name='countdown_reset'),
url(r'^countdown/start/$',
views.CountdownEdit.as_view(),
views.CountdownControllView.as_view(),
{'command': 'start'},
name='countdown_start'),
url(r'^countdown/stop/$',
views.CountdownEdit.as_view(),
views.CountdownControllView.as_view(),
{'command': 'stop'},
name='countdown_stop'),
url(r'^countdown/set-default/$',
views.CountdownEdit.as_view(),
views.CountdownControllView.as_view(),
{'command': 'set-default'},
name='countdown_set_default'),

View File

@ -22,8 +22,8 @@ from openslides.utils.template import Tab
from openslides.utils.views import (AjaxMixin, CreateView, DeleteView,
RedirectView, TemplateView, UpdateView)
from .api import (get_active_slide, get_all_widgets, get_overlays,
get_projector_content, get_projector_overlays,
from .api import (call_on_projector, get_active_slide, get_all_widgets,
get_overlays, get_projector_content, get_projector_overlays,
get_projector_overlays_js, reset_countdown, set_active_slide,
start_countdown, stop_countdown, update_projector_overlay)
from .forms import SelectWidgetsForm
@ -64,8 +64,8 @@ class Projector(TemplateView):
'content': get_projector_content(),
'overlays': get_projector_overlays(),
'overlay_js': get_projector_overlays_js(),
'reload': True})
'reload': True,
'calls': config['projector_js_cache']})
# For the Preview
else:
kwargs.update({
@ -85,8 +85,8 @@ class ActivateView(RedirectView):
def pre_redirect(self, request, *args, **kwargs):
set_active_slide(kwargs['callback'], kwargs=dict(request.GET.items()))
config['up'] = 0
config['bigger'] = 100
config['projector_scroll'] = config.get_default('projector_scroll')
config['projector_scale'] = config.get_default('projector_scale')
class SelectWidgetsView(TemplateView):
@ -133,7 +133,7 @@ class SelectWidgetsView(TemplateView):
return redirect(reverse('dashboard'))
class ProjectorEdit(RedirectView):
class ProjectorControllView(RedirectView):
"""
Scale or scroll the projector.
"""
@ -144,20 +144,23 @@ class ProjectorEdit(RedirectView):
def pre_redirect(self, request, *args, **kwargs):
direction = kwargs['direction']
if direction == 'bigger':
config['bigger'] = int(config['bigger']) + 20
config['projector_scale'] = int(config['projector_scale']) + 20
elif direction == 'smaller':
config['bigger'] = int(config['bigger']) - 20
config['projector_scale'] = int(config['projector_scale']) - 20
elif direction == 'down':
config['up'] = int(config['up']) - 5
config['projector_scroll'] = int(config['projector_scroll']) - 5
elif direction == 'up':
if config['up'] < 0:
config['up'] = int(config['up']) + 5
if config['projector_scroll'] < 0:
config['projector_scroll'] = int(config['projector_scroll']) + 5
elif direction == 'clean':
config['up'] = config.get_default('up')
config['bigger'] = config.get_default('bigger')
config['projector_scroll'] = config.get_default('projector_scroll')
config['projector_scale'] = config.get_default('projector_scale')
call_on_projector({'scroll': config['projector_scroll'],
'scale': config['projector_scale']})
class CountdownEdit(RedirectView):
class CountdownControllView(RedirectView):
"""
Start, stop or reset the countdown.
"""

View File

@ -57,9 +57,9 @@ class ProjectorSocketHandler(WebSocketHandler):
ProjectorSocketHandler.waiters.remove(self)
@classmethod
def send_updates(cls, slide):
def send_updates(cls, data):
for waiter in cls.waiters:
waiter.write_message(slide)
waiter.write_message(data)
def run_tornado(addr, port, reload=False):