1
# Copyright (C) 2007, One Laptop Per Child
3
# This library is free software; you can redistribute it and/or
4
# modify it under the terms of the GNU Lesser General Public
5
# License as published by the Free Software Foundation; either
6
# version 2 of the License, or (at your option) any later version.
8
# This library is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
# Lesser General Public License for more details.
13
# You should have received a copy of the GNU Lesser General Public
14
# License along with this library; if not, write to the
15
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16
# Boston, MA 02111-1307, USA.
25
from sugar.graphics import style
26
from sugar.graphics.icon import Icon
28
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
30
class Alert(gtk.EventBox):
31
"""UI interface for Alerts
33
Alerts are used inside the activity window instead of being a
34
separate popup window. They do not hide canvas content. You can
35
use add_alert(widget) and remove_alert(widget) inside your activity
36
to add and remove the alert. The position of the alert is below the
37
toolbox or top in fullscreen mode.
40
'title': the title of the alert,
41
'message': the message of the alert,
42
'icon': the icon that appears at the far left
46
__gtype_name__ = 'SugarAlert'
49
'response': (gobject.SIGNAL_RUN_FIRST,
50
gobject.TYPE_NONE, ([object]))
54
'title' : (str, None, None, None,
55
gobject.PARAM_READWRITE),
56
'msg' : (str, None, None, None,
57
gobject.PARAM_READWRITE),
58
'icon' : (object, None, None,
59
gobject.PARAM_WRITABLE)
62
def __init__(self, **kwargs):
69
self._hbox = gtk.HBox()
70
self._hbox.set_border_width(style.DEFAULT_SPACING)
71
self._hbox.set_spacing(style.DEFAULT_SPACING)
73
self._msg_box = gtk.VBox()
74
self._title_label = gtk.Label()
75
self._title_label.set_alignment(0, 0.5)
76
self._msg_box.pack_start(self._title_label, False)
78
self._msg_label = gtk.Label()
79
self._msg_label.set_alignment(0, 0.5)
80
self._msg_box.pack_start(self._msg_label, False)
81
self._hbox.pack_start(self._msg_box, False)
83
self._buttons_box = gtk.HButtonBox()
84
self._buttons_box.set_layout(gtk.BUTTONBOX_END)
85
self._buttons_box.set_spacing(style.DEFAULT_SPACING)
86
self._hbox.pack_start(self._buttons_box)
88
gtk.EventBox.__init__(self, **kwargs)
90
self.set_visible_window(True)
92
self._title_label.show()
93
self._msg_label.show()
94
self._buttons_box.show()
99
def do_set_property(self, pspec, value):
100
if pspec.name == 'title':
101
if self._title != value:
103
self._title_label.set_markup("<b>" + self._title + "</b>")
104
elif pspec.name == 'msg':
105
if self._msg != value:
107
self._msg_label.set_markup(self._msg)
108
elif pspec.name == 'icon':
109
if self._icon != value:
111
self._hbox.pack_start(self._icon, False)
112
self._hbox.reorder_child(self._icon, 0)
114
def do_get_property(self, pspec):
115
if pspec.name == 'title':
117
elif pspec.name == 'msg':
120
def add_button(self, response_id, label, icon=None, position=-1):
121
"""Add a button to the alert
123
response_id: will be emitted with the response signal
124
a response ID should one of the pre-defined
125
GTK Response Type Constants or a positive number
126
label: that will occure right to the buttom
127
icon: this can be a SugarIcon or a gtk.Image
128
position: the position of the button in the box (optional)
130
button = gtk.Button()
131
self._buttons[response_id] = button
133
button.set_image(icon)
134
button.set_label(label)
135
self._buttons_box.pack_start(button)
137
button.connect('clicked', self.__button_clicked_cb, response_id)
139
self._buttons_box.reorder_child(button, position)
142
def remove_button(self, response_id):
143
"""Remove a button from the alert by the given response id"""
144
self._buttons_box.remove(self._buttons[response_id])
146
def _response(self, response_id):
147
"""Emitting response when we have a result
149
A result can be that a user has clicked a button or
150
a timeout has occured, the id identifies the button
151
that has been clicked and -1 for a timeout
153
self.emit('response', response_id)
155
def __button_clicked_cb(self, button, response_id):
156
self._response(response_id)
159
class ConfirmationAlert(Alert):
160
"""This is a ready-made two button (Cancel,Ok) alert"""
162
def __init__(self, **kwargs):
163
Alert.__init__(self, **kwargs)
165
icon = Icon(icon_name='dialog-cancel')
166
self.add_button(gtk.RESPONSE_CANCEL, _('Cancel'), icon)
169
icon = Icon(icon_name='dialog-ok')
170
self.add_button(gtk.RESPONSE_OK, _('Ok'), icon)
174
class _TimeoutIcon(hippo.CanvasText, hippo.CanvasItem):
175
"""An icon with a round border"""
176
__gtype_name__ = 'AlertTimeoutIcon'
178
def __init__(self, **kwargs):
179
hippo.CanvasText.__init__(self, **kwargs)
181
self.props.orientation = hippo.ORIENTATION_HORIZONTAL
182
self.props.border_left = style.DEFAULT_SPACING
183
self.props.border_right = style.DEFAULT_SPACING
185
def do_paint_background(self, cr, damaged_box):
186
[width, height] = self.get_allocation()
190
radius = min(width * 0.5, height * 0.5)
192
hippo.cairo_set_source_rgba32(cr, self.props.background_color)
193
cr.arc(xval, yval, radius, 0, 2*math.pi)
197
class TimeoutAlert(Alert):
198
"""This is a ready-made two button (Cancel,Continue) alert
200
It times out with a positive reponse after the given amount of seconds.
203
def __init__(self, timeout=5, **kwargs):
204
Alert.__init__(self, **kwargs)
206
self._timeout = timeout
208
icon = Icon(icon_name='dialog-cancel')
209
self.add_button(gtk.RESPONSE_CANCEL, _('Cancel'), icon)
212
self._timeout_text = _TimeoutIcon(
214
color=style.COLOR_BUTTON_GREY.get_int(),
215
background_color=style.COLOR_WHITE.get_int())
216
canvas = hippo.Canvas()
217
canvas.set_root(self._timeout_text)
219
self.add_button(gtk.RESPONSE_OK, _('Continue'), canvas)
221
gobject.timeout_add(1000, self.__timeout)
225
self._timeout_text.props.text = self._timeout
226
if self._timeout == 0:
227
self._response(gtk.RESPONSE_OK)
232
class NotifyAlert(Alert):
233
"""Timeout alert with only an "OK" button - just for notifications"""
235
def __init__(self, timeout=5, **kwargs):
236
Alert.__init__(self, **kwargs)
238
self._timeout = timeout
240
self._timeout_text = _TimeoutIcon(
242
color=style.COLOR_BUTTON_GREY.get_int(),
243
background_color=style.COLOR_WHITE.get_int())
244
canvas = hippo.Canvas()
245
canvas.set_root(self._timeout_text)
247
self.add_button(gtk.RESPONSE_OK, _('Ok'), canvas)
249
gobject.timeout_add(1000, self.__timeout)
253
self._timeout_text.props.text = self._timeout
254
if self._timeout == 0:
255
self._response(gtk.RESPONSE_OK)