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 #: projector/templates/projector/control.html:193
msgid "sec" msgid "sec"
msgstr "s" msgstr "sek"
#: projector/templates/projector/control.html:194 #: projector/templates/projector/control.html:194
msgid "Save as default" 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. * :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() { $(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 an element to show it on projector
$('.activate_link').click(function(event) { $('.activate_link').click(function(event) {
event.preventDefault(); event.preventDefault();
@ -14,7 +92,6 @@ $(function() {
type: 'GET', type: 'GET',
url: $(this).attr('href'), url: $(this).attr('href'),
dataType: 'json', dataType: 'json',
data: '',
success: function(data) { success: function(data) {
$('.activate_link').removeClass('active'); $('.activate_link').removeClass('active');
$('li').removeClass('activeline'); $('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 // control the projector
$('.projector_edit').click(function(event) { $('.projector_edit').click(function(event) {
event.preventDefault(); event.preventDefault();
@ -42,7 +138,7 @@ $(function() {
}); });
// control countdown // control countdown
$('.projector_countdown_btn').click(function(event) { $('.countdown_control').click(function(event) {
event.preventDefault(); event.preventDefault();
var link = $(this); var link = $(this);
var requestData = {}; var requestData = {};
@ -56,6 +152,14 @@ $(function() {
data: requestData, data: requestData,
dataType: 'json', dataType: 'json',
success: function(data) { 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 {*/ /*.projector_countdown_spinval {*/
#countdown_time { #countdown_time {
width: 40px; width: 40px;
height: 16px; 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 */
#iframe { #iframe {
-moz-transform-origin: 0 0; -moz-transform-origin: 0 0;
@ -127,3 +90,22 @@ a.activate_link div {
a.activate_link.active div { a.activate_link.active div {
background-image: url(../images/icons/accept.png); 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/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/projector-control.js' %}"></script>
<script type="text/javascript" src="{% static 'javascript/jquery.cookie.js' %}"></script> <script type="text/javascript" src="{% static 'javascript/jquery.cookie.js' %}"></script>
<script type="text/javascript"> <script type="text/javascript" src="{% static 'javascript/jquery.form.js' %}"></script>
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>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
@ -180,55 +68,27 @@
<div class="portlet" id="portlet_overlays"> <div class="portlet" id="portlet_overlays">
<div class="portlet-header">{% trans 'Overlays' %}</div> <div class="portlet-header">{% trans 'Overlays' %}</div>
<div class="portlet-content"> <div class="portlet-content">
<ul style="line-height: 180%"> <ul>
<form action="" method="post">{% csrf_token %} {% for overlay in overlays %}
<ul> <li>
{% for overlay in overlays %} <a id="{{ overlay.def_name }}_inactive" href="{% url projector_overlay_activate overlay.def_name %}" class="overlay"{% if overlay.active %} style="display:none"{% endif %}>
<li> <div></div>
<input type="checkbox" name="{{ overlay.def_name }}" onchange="submit()" </a>
{% if overlay.active %} checked="checked"{% endif %}> {{ overlay }}: <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 %}>
{# Countdown #} <div></div>
{% if overlay.def_name == "Countdown" %} </a>
<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" %} {{ overlay }}:
<a id="countdown_set" class="projector_countdown_btn" href="{% url countdown_set_default %}" title="{% trans 'Save as default' %}"> {# TODO: Call the html via overlay.html #}
<img src="{% static 'images/icons/document-save.png' %}" /> {# Countdown #}
</a> {% if overlay.def_name == "Countdown" %}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {% include 'projector/control_countdown.html' %}
<a class="projector_countdown_btn" href="{% url countdown_reset %}" title="{% trans 'Reset countdown' %}" onclick="javascript:switchButtons('play')"> {% endif %}
<button type="submit" class="button" style="padding:4px;" name='message-clean'> {% if overlay.def_name == "Message" %}
<span class="icon backward">&nbsp;</span> {% include 'projector/control_overlay_message.html' %}
</button></a>&nbsp; {% endif %}
<a id="countdown_play" class="projector_countdown_btn" href="{% url countdown_start %}" title="{% trans 'Start countdown' %}" onclick="javascript:switchButtons('stop')"><button </li>
type="submit" class="button" style="padding:4px;" name='message-clean'> {% endfor %}
<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> </ul>
</div> </div>
</div> <!-- end portlet--> </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.models import ProjectorSlide
from openslides.projector.views import (ControlView, ActivateView, from openslides.projector.views import (ControlView, ActivateView,
CustomSlideCreateView, CustomSlideUpdateView, CustomSlideDeleteView, CustomSlideCreateView, CustomSlideUpdateView, CustomSlideDeleteView,
CountdownEdit, ProjectorEdit, Projector) CountdownEdit, ProjectorEdit, Projector, ActivateOverlay)
urlpatterns = patterns('projector.views', urlpatterns = patterns('projector.views',
@ -99,20 +98,6 @@ urlpatterns = patterns('projector.views',
## name='countdown_edit', ## 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/$', url(r'^countdown/reset/$',
CountdownEdit.as_view(), CountdownEdit.as_view(),
{'command': 'reset'}, {'command': 'reset'},
@ -136,4 +121,16 @@ urlpatterns = patterns('projector.views',
{'command': 'set-default'}, {'command': 'set-default'},
name='countdown_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 from openslides.projector.signals import projector_overlays
class ControlView(TemplateView): class ControlView(TemplateView, AjaxMixin):
template_name = 'projector/control.html' template_name = 'projector/control.html'
permission_required = 'projector.can_manage_projector' permission_required = 'projector.can_manage_projector'
@ -64,6 +64,8 @@ class ControlView(TemplateView):
else: else:
overlay.active = False overlay.active = False
overlay.save() overlay.save()
if request.is_ajax():
return ajax_get(request, *args, **kwargs)
return self.get(request, *args, **kwargs) return self.get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -94,6 +96,32 @@ class ControlView(TemplateView):
return context 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): class ActivateView(RedirectView):
url = 'projector_control' url = 'projector_control'
allow_ajax = True allow_ajax = True
@ -244,6 +272,7 @@ class CountdownEdit(RedirectView):
def pre_redirect(self, request, *args, **kwargs): def pre_redirect(self, request, *args, **kwargs):
command = kwargs['command'] command = kwargs['command']
# countdown_state is one of 'inactive', 'paused' and 'active', 'expired'
if command in ['reset', 'start', 'stop']: if command in ['reset', 'start', 'stop']:
config['countdown_time'] = config['countdown_time'] config['countdown_time'] = config['countdown_time']
@ -276,6 +305,12 @@ class CountdownEdit(RedirectView):
except AttributeError: except AttributeError:
pass pass
def get_ajax_context(self, **kwargs):
return {
'state': config['countdown_state'],
'countdown_time': config['countdown_time'],
}
def register_tab(request): def register_tab(request):
selected = True if request.path.startswith('/projector/') else False selected = True if request.path.startswith('/projector/') else False