rewrote projector overlay widget

This commit is contained in:
Oskar Hahn 2012-07-04 02:43:26 +02:00
parent 2dc0cc83f1
commit 198eefbfdd
10 changed files with 1311 additions and 220 deletions

View File

@ -2105,7 +2105,7 @@ msgstr "Einblendungen"
#: projector/templates/projector/control.html:193
msgid "sec"
msgstr "s"
msgstr "sek"
#: projector/templates/projector/control.html:194
msgid "Save as default"

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,85 @@
* :license: GNU GPL, see LICENSE for more details.
*/
// function that writes the portlet list order to a cookie
function saveOrder() {
$(".column").each(function(index, value){
var colid = value.id;
var cookieName = "cookie-" + colid;
// Get the order for this column.
var order = $('#' + colid).sortable("toArray");
// For each portlet in the column
for ( var i = 0, n = order.length; i < n; i++ ) {
// Determine if it is 'opened' or 'closed'
var v = $('#' + order[i] ).find('.portlet-content').is(':visible');
// Modify the array we're saving to indicate what's open and
// what's not.
order[i] = order[i] + ":" + v;
}
$.cookie(cookieName, order, { path: "/", expiry: new Date(2012, 1, 1)});
});
}
// function that restores the portlet list order from a cookie
function restoreOrder() {
$(".column").each(function(index, value) {
var colid = value.id;
var cookieName = "cookie-" + colid
var cookie = $.cookie(cookieName);
if ( cookie == null ) { return; }
var IDs = cookie.split(",");
for (var i = 0, n = IDs.length; i < n; i++ ) {
var toks = IDs[i].split(":");
if ( toks.length != 2 ) {
continue;
}
var portletID = toks[0];
var visible = toks[1]
var portlet = $(".column")
.find('#' + portletID)
.appendTo($('#' + colid));
if (visible === 'false') {
portlet.find(".ui-icon").toggleClass("ui-icon-minus");
portlet.find(".ui-icon").toggleClass("ui-icon-plus");
portlet.find(".portlet-content").hide();
}
}
});
}
$(function() {
$( ".column" ).sortable({
connectWith: ".column",
stop: function() { saveOrder(); }
});
$(".portlet")
.addClass("ui-widget ui-widget-content")
.addClass("ui-helper-clearfix ui-corner-all")
.find(".portlet-header")
.addClass("ui-widget-header ui-corner-all")
.prepend('<span class="ui-icon ui-icon-minus"></span>')
.end()
.find(".portlet-content");
restoreOrder();
$(".portlet-header .ui-icon").click(function() {
$(this).toggleClass("ui-icon-minus");
$(this).toggleClass("ui-icon-plus");
$(this).parents(".portlet:first").find(".portlet-content").toggle();
saveOrder(); // This is important
});
if ($.browser.msie) {
if ($.browser.version >= 8.0 && $.browser.version < 9.0)
{
/* scaling bug in IE8.. iframe has to be 4 times bigger */
$( "#iframe" ).css('width', 1024 * 4);
$( "#iframe" ).css('height', 768 * 4);
}
$( "#iframe" ).css('zoom', '0.25');
}
// activate an element to show it on projector
$('.activate_link').click(function(event) {
event.preventDefault();
@ -14,7 +92,6 @@ $(function() {
type: 'GET',
url: $(this).attr('href'),
dataType: 'json',
data: '',
success: function(data) {
$('.activate_link').removeClass('active');
$('li').removeClass('activeline');
@ -28,6 +105,25 @@ $(function() {
});
});
$('a.overlay').click(function(event) {
event.preventDefault();
var link = $(this);
$.ajax({
type: 'GET',
url: $(this).attr('href'),
dataType: 'json',
success: function(data) {
if (data['active']) {
$('#' + data['def_name'] + '_active').show();
$('#' + data['def_name'] + '_inactive').hide();
} else {
$('#' + data['def_name'] + '_active').hide();
$('#' + data['def_name'] + '_inactive').show();
}
},
});
});
// control the projector
$('.projector_edit').click(function(event) {
event.preventDefault();
@ -42,7 +138,7 @@ $(function() {
});
// control countdown
$('.projector_countdown_btn').click(function(event) {
$('.countdown_control').click(function(event) {
event.preventDefault();
var link = $(this);
var requestData = {};
@ -56,6 +152,14 @@ $(function() {
data: requestData,
dataType: 'json',
success: function(data) {
if (data['state'] == 'active') {
$('#countdown_play').hide();
$('#countdown_stop').show();
} else {
$('#countdown_play').show();
$('#countdown_stop').hide();
}
$('#countdown_time').val(data['countdown_time'])
}
});
});
@ -78,4 +182,8 @@ $(function() {
}
});
});
$('#overlay-form').ajaxForm(function() {
alert("Thank you for your comment!");
});
});

View File

@ -39,49 +39,12 @@
}
/*.projector_countdown_spinval {*/
#countdown_time {
width: 40px;
height: 16px;
}
.projector_countdown_spinbox {
height: 16px;
width: auto;
position: relative;
display: inline-block;
}
.projector_countdown_spinup {
position: absolute;
top: 0px;
left: 35px;
}
.projector_countdown_spindown {
position: absolute;
top: 8px;
left: 35px;
}
.projector_countdown_btn img {
padding-top: 8px;
position: absolute;
}
/* countdown control buttons */
.play{
background:url(../images/icons/play.png) no-repeat 0px 0px;
text-indent: 14px !important;
}
.pause{
background:url(../images/icons/pause.png) no-repeat 0px 0px;
text-indent: 14px !important;
}
.backward{
background:url(../images/icons/skip-backward.png) no-repeat 0px 0px;
text-indent: 14px !important;
}
/* iframe */
#iframe {
-moz-transform-origin: 0 0;
@ -127,3 +90,22 @@ a.activate_link div {
a.activate_link.active div {
background-image: url(../images/icons/accept.png);
}
a.overlay div {
background-image: url(../images/icons/accept-grey.png);
background-repeat: no-repeat;
float: left;
width: 16px;
height: 16px;
padding-right: 16px;
position: relative;
top: 4px;
left: 4px;
}
a.overlay.active div {
background-image: url(../images/icons/accept.png);
}

View File

@ -10,119 +10,7 @@
<script type="text/javascript" src="{% static 'javascript/jquery-ui-1.8.18.custom.min.js' %}"></script>
<script type="text/javascript" src="{% static 'javascript/projector-control.js' %}"></script>
<script type="text/javascript" src="{% static 'javascript/jquery.cookie.js' %}"></script>
<script type="text/javascript">
function switchButtons(which) {
if (which == 'stop') {
$( "#countdown_play" ).hide();
$( "#countdown_stop" ).show();
}
else {
$( "#countdown_play" ).show();
$( "#countdown_stop" ).hide();
}
return true;
};
function spinCount(delta) {
var count = parseInt($( "#countdown_time" ).val());
if (count + delta < 0) {
delta = 0;
}
$( "#countdown_time" ).val(count + delta);
return false;
};
// function that writes the portlet list order to a cookie
function saveOrder() {
$(".column").each(function(index, value){
var colid = value.id;
var cookieName = "cookie-" + colid;
// Get the order for this column.
var order = $('#' + colid).sortable("toArray");
// For each portlet in the column
for ( var i = 0, n = order.length; i < n; i++ ) {
// Determine if it is 'opened' or 'closed'
var v = $('#' + order[i] ).find('.portlet-content').is(':visible');
// Modify the array we're saving to indicate what's open and
// what's not.
order[i] = order[i] + ":" + v;
}
$.cookie(cookieName, order, { path: "/", expiry: new Date(2012, 1, 1)});
});
}
// function that restores the portlet list order from a cookie
function restoreOrder() {
$(".column").each(function(index, value) {
var colid = value.id;
var cookieName = "cookie-" + colid
var cookie = $.cookie(cookieName);
if ( cookie == null ) { return; }
var IDs = cookie.split(",");
for (var i = 0, n = IDs.length; i < n; i++ ) {
var toks = IDs[i].split(":");
if ( toks.length != 2 ) {
continue;
}
var portletID = toks[0];
var visible = toks[1]
var portlet = $(".column")
.find('#' + portletID)
.appendTo($('#' + colid));
if (visible === 'false') {
portlet.find(".ui-icon").toggleClass("ui-icon-minus");
portlet.find(".ui-icon").toggleClass("ui-icon-plus");
portlet.find(".portlet-content").hide();
}
}
});
}
$(function() {
$( ".column" ).sortable({
connectWith: ".column",
stop: function() { saveOrder(); }
});
$(".portlet")
.addClass("ui-widget ui-widget-content")
.addClass("ui-helper-clearfix ui-corner-all")
.find(".portlet-header")
.addClass("ui-widget-header ui-corner-all")
.prepend('<span class="ui-icon ui-icon-minus"></span>')
.end()
.find(".portlet-content");
restoreOrder();
$(".portlet-header .ui-icon").click(function() {
$(this).toggleClass("ui-icon-minus");
$(this).toggleClass("ui-icon-plus");
$(this).parents(".portlet:first").find(".portlet-content").toggle();
saveOrder(); // This is important
});
$( "document" ).ready(function(){
if ($.browser.msie) {
if ($.browser.version >= 8.0 && $.browser.version < 9.0)
{
/* scaling bug in IE8.. iframe has to be 4 times bigger */
$( "#iframe" ).css('width', 1024 * 4);
$( "#iframe" ).css('height', 768 * 4);
}
$( "#iframe" ).css('zoom', '0.25');
}
{% if countdown_state == "active" %}
switchButtons('stop');
{% else %}
switchButtons('play');
{% endif %}
});
});
</script>
<script type="text/javascript" src="{% static 'javascript/jquery.form.js' %}"></script>
{% endblock %}
{% block content %}
@ -180,55 +68,27 @@
<div class="portlet" id="portlet_overlays">
<div class="portlet-header">{% trans 'Overlays' %}</div>
<div class="portlet-content">
<ul style="line-height: 180%">
<form action="" method="post">{% csrf_token %}
<ul>
{% for overlay in overlays %}
<li>
<input type="checkbox" name="{{ overlay.def_name }}" onchange="submit()"
{% if overlay.active %} checked="checked"{% endif %}> {{ overlay }}:
{# Countdown #}
{% if overlay.def_name == "Countdown" %}
<span class="projector_countdown_spinbox">
<input class="projector_countdown_spinval" id="countdown_time" name="countdown_time" type="number" min="0" value="{{countdown_time}}">{% trans "sec" %}
<a id="countdown_set" class="projector_countdown_btn" href="{% url countdown_set_default %}" title="{% trans 'Save as default' %}">
<img src="{% static 'images/icons/document-save.png' %}" />
</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a class="projector_countdown_btn" href="{% url countdown_reset %}" title="{% trans 'Reset countdown' %}" onclick="javascript:switchButtons('play')">
<button type="submit" class="button" style="padding:4px;" name='message-clean'>
<span class="icon backward">&nbsp;</span>
</button></a>&nbsp;
<a id="countdown_play" class="projector_countdown_btn" href="{% url countdown_start %}" title="{% trans 'Start countdown' %}" onclick="javascript:switchButtons('stop')"><button
type="submit" class="button" style="padding:4px;" name='message-clean'>
<span class="icon play">&nbsp;</span>
</button></a>
<a id="countdown_stop" class="projector_countdown_btn" href="{% url countdown_stop %}" title="{% trans 'Stop countdown' %}" onclick="javascript:switchButtons('play')">
<button type="submit" class="button" style="padding:4px;" name='message-clean'>
<span class="icon pause">&nbsp;</span>
</button>
</a>
</span>
<p></p>
{% endif %}
{% if overlay.def_name == "Message" %}
<nobr>
<input name='message_text' type='text' style='width: 70%'
value="{% get_config 'projector_message' %}">
<button type="submit"
class="button" style="padding:4px 0;" name='message-clean' title="{% trans 'Clean message' %}">
<span class="icon clear">&nbsp;</span>
</button>
</nobr>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button type="submit" class="button" name='message'>
<span class="icon ok">{% trans 'Apply' %}</span>
</button>
{% endif %}
</li>
{% endfor %}
</ul>
</form>
<ul>
{% for overlay in overlays %}
<li>
<a id="{{ overlay.def_name }}_inactive" href="{% url projector_overlay_activate overlay.def_name %}" class="overlay"{% if overlay.active %} style="display:none"{% endif %}>
<div></div>
</a>
<a id="{{ overlay.def_name }}_active" href="{% url projector_overlay_deactivate overlay.def_name %}" class="overlay active"{% if not overlay.active %} style="display:none"{% endif %}>
<div></div>
</a>
{{ overlay }}:
{# TODO: Call the html via overlay.html #}
{# Countdown #}
{% if overlay.def_name == "Countdown" %}
{% include 'projector/control_countdown.html' %}
{% endif %}
{% if overlay.def_name == "Message" %}
{% include 'projector/control_overlay_message.html' %}
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div> <!-- end portlet-->

View File

@ -0,0 +1,19 @@
{% load staticfiles %}
{% load i18n %}
{% load tags %}
<span class="projector_countdown_spinbox">
<input class="projector_countdown_spinval" id="countdown_time" name="countdown_time" type="number" min="0" value="{{ countdown_time }}"> {% trans "sec" %}
<a id="countdown_set" class="countdown_control" href="{% url countdown_set_default %}" title="{% trans 'Save as default' %}">
<img src="{% static 'images/icons/document-save.png' %}" alt="{% url countdown_set_default %}">
</a>
<a id="countdown_reset" class="countdown_control" href="{% url countdown_reset %}" title="{% trans 'Reset countdown' %}">
<img src="{% static 'images/icons/skip-backward.png' %}" alt="{% trans 'Reset countdown' %}">
</a>
<a id="countdown_play" class="countdown_control" href="{% url countdown_start %}" title="{% trans 'Start countdown' %}"{% if countdown_state == 'active' %} style="display:none"{% endif %}>
<img src="{% static 'images/icons/play.png' %}" alt="{% url countdown_start %}">
</a>
<a id="countdown_stop" class="countdown_control" href="{% url countdown_stop %}" title="{% trans 'Stop countdown' %}"{% if countdown_state == 'inactive' or countdown_state == 'paused' or countdown_state == 'expired' %} style="display:none"{% endif %}>
<img src="{% static 'images/icons/pause.png' %}" alt="{% url countdown_stop %}">
</a>
</span>

View File

@ -0,0 +1,14 @@
{% load staticfiles %}
{% load i18n %}
{% load tags %}
<form id="overlay-form" action="" method="post" style="display:inline">{% csrf_token %}
<input name='message_text' type='text' style='width: 40%' value="{% get_config 'projector_message' %}">
<button type="submit" class="button" name='message'>
<span class="icon ok">{% trans 'Apply' %}</span>
</button>
<button type="submit"
class="button" style="padding:4px 0;" name='message-clean' title="{% trans 'Clean message' %}">
<span class="icon clear">&nbsp;</span>
</button>
</form>

View File

@ -17,8 +17,7 @@ from openslides.utils.views import CreateView
from openslides.projector.models import ProjectorSlide
from openslides.projector.views import (ControlView, ActivateView,
CustomSlideCreateView, CustomSlideUpdateView, CustomSlideDeleteView,
CountdownEdit, ProjectorEdit, Projector)
CountdownEdit, ProjectorEdit, Projector, ActivateOverlay)
urlpatterns = patterns('projector.views',
@ -99,20 +98,6 @@ urlpatterns = patterns('projector.views',
## name='countdown_edit',
## ),
url(r'^countdown/show/$',
CountdownEdit.as_view(),
{'command': 'show'},
name='countdown_open',
),
url(r'^countdown/hide/$',
CountdownEdit.as_view(),
{'command': 'hide'},
name='countdown_close',
),
url(r'^countdown/reset/$',
CountdownEdit.as_view(),
{'command': 'reset'},
@ -136,4 +121,16 @@ urlpatterns = patterns('projector.views',
{'command': 'set-default'},
name='countdown_set_default',
),
url('^overlay/(?P<name>[^/]*)/activate/$',
ActivateOverlay.as_view(),
{'activate': True},
name='projector_overlay_activate',
),
url('^overlay/(?P<name>[^/]*)/deactivate/$',
ActivateOverlay.as_view(),
{'activate': False},
name='projector_overlay_deactivate',
),
)

View File

@ -35,7 +35,7 @@ from openslides.projector.models import ProjectorOverlay, ProjectorSlide
from openslides.projector.signals import projector_overlays
class ControlView(TemplateView):
class ControlView(TemplateView, AjaxMixin):
template_name = 'projector/control.html'
permission_required = 'projector.can_manage_projector'
@ -64,6 +64,8 @@ class ControlView(TemplateView):
else:
overlay.active = False
overlay.save()
if request.is_ajax():
return ajax_get(request, *args, **kwargs)
return self.get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
@ -94,6 +96,32 @@ class ControlView(TemplateView):
return context
class ActivateOverlay(RedirectView):
url = 'projector_control'
allow_ajax = True
@property
def overlay(self):
try:
return self._overlay
except AttributeError:
self._overlay = ProjectorOverlay.objects.get(def_name=self.kwargs['name'])
return self._overlay
def pre_redirect(self, request, *args, **kwargs):
if kwargs['activate']:
self.overlay.active = True
else:
self.overlay.active = False
self.overlay.save()
def get_ajax_context(self, **kwargs):
return {
'active': self.overlay.active,
'def_name': self.overlay.def_name,
}
class ActivateView(RedirectView):
url = 'projector_control'
allow_ajax = True
@ -244,6 +272,7 @@ class CountdownEdit(RedirectView):
def pre_redirect(self, request, *args, **kwargs):
command = kwargs['command']
# countdown_state is one of 'inactive', 'paused' and 'active', 'expired'
if command in ['reset', 'start', 'stop']:
config['countdown_time'] = config['countdown_time']
@ -276,6 +305,12 @@ class CountdownEdit(RedirectView):
except AttributeError:
pass
def get_ajax_context(self, **kwargs):
return {
'state': config['countdown_state'],
'countdown_time': config['countdown_time'],
}
def register_tab(request):
selected = True if request.path.startswith('/projector/') else False