Send js to the projector
* fixed scroll and scale of the projector
This commit is contained in:
parent
d714ac0223
commit
82f0df4fea
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 %}
|
||||
|
||||
{% endif %}
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
{% else %}
|
||||
|
||||
{% 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>
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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")
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -0,0 +1,9 @@
|
||||
{% load i18n %}
|
||||
|
||||
<h1>{{ slide.title }}</h1>
|
||||
|
||||
<div class="scroll">
|
||||
{% if slide.text %}
|
||||
<span>{{ slide.text|safe|linebreaks }}</span>
|
||||
{% endif %}
|
||||
</div>
|
@ -1,7 +0,0 @@
|
||||
{% load i18n %}
|
||||
|
||||
<h1>{{ slide.title }}</h1>
|
||||
|
||||
{% if slide.text %}
|
||||
<span>{{ slide.text|safe|linebreaks }}</span>
|
||||
{% endif %}
|
@ -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'),
|
||||
|
||||
|
@ -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.
|
||||
"""
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user