#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2008 Adriano Monteiro Marques
#
# Author: Francesco Piccinno <stack.box@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
HIGAnimatedBar a widget like firefox bar
"""
import gtk
import gobject
class HIGAnimatedBar(gtk.EventBox):
"""
A dummy animated bar to show message like Firefox one.
"""
__gtype_name__ = "HIGAnimatedBar"
def __init__(self, msg, stock=gtk.STOCK_DIALOG_INFO, file=None, markup=True):
"""
Create a HIGAnimatedBar
The stock option have priority.
@param msg the message to show in the label
@param stock the stock for gtk.Image
@param file the file to use with gtk.Image
@param markup if label should use markup
"""
gtk.EventBox.__init__(self)
if stock:
self._image = gtk.image_new_from_stock(stock, gtk.ICON_SIZE_MENU)
elif file:
self._image = gtk.image_new_from_file(file)
self._markup = True
self._label = gtk.Label(msg)
self._label.set_use_markup(markup)
self._label.set_alignment(0, 0.5)
self._close = gtk.Button()
self._close.add(gtk.image_new_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU))
self._close.set_relief(gtk.RELIEF_NONE)
self._close.connect('clicked', self.__on_close)
self._hbox = gtk.HBox()
self._hbox.set_spacing(4)
self._hbox.set_border_width(2)
self._hbox.pack_start(self._image, False, False, 0)
self._hbox.pack_start(self._label)
self._hbox.pack_start(self._close, False, False, 0)
self._frame = gtk.Frame()
self._frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
self._frame.add(self._hbox)
self._frame.show_all()
self.add(self._frame)
self.set_redraw_on_allocate(False)
self._animate = False
self._show = True
self._max_height = 0
self._first_expose = True
self._animate_id = None
self._current_height = 0
def do_size_allocate(self, alloc):
if self._animate:
if self._show: self._current_height += 5
else: self._current_height -= 5
alloc.height = self._current_height
if not self._show and alloc.height <= 0:
self._animate = False
alloc.height = 0
# uhm?
self.hide()
if self._show and alloc.height >= self._max_height:
self._animate = False
alloc.height = self._max_height
# Check the max height
if self._max_height > 0 and alloc.height >= self._max_height:
alloc.height = self._max_height
gtk.EventBox.do_size_allocate(self, alloc)
def do_expose_event(self, evt):
if self._first_expose:
alloc = self.allocation; alloc.height = 0
self.do_size_allocate(alloc)
if self.flags() & gtk.VISIBLE:
self.start_animation(True)
self._first_expose = False
return gtk.EventBox.do_expose_event(self, evt)
def do_realize(self):
gtk.EventBox.do_realize(self)
self.bg_color = gtk.gdk.color_parse("#FFFFDC")
gtk.gdk.colormap_get_system().alloc_color(self.bg_color)
# NB: Should we add more colors here?
self.modify_bg(gtk.STATE_NORMAL, self.bg_color)
self._max_height = self._frame.size_request()[1]
alloc = self.allocation; alloc.height = 0
self.do_size_allocate(self.allocation)
def __do_animation(self):
"""
callback for timeout_add
"""
self.do_size_allocate(self.allocation)
return self._animate
def __on_close(self, widget):
self.start_animation(False)
def start_animation(self, show):
"""
Start the animation
@param show if the widget will be showed or hided
"""
self._animate = True
self._show = show
if show:
if not self.flags() & gtk.VISIBLE:
self.show()
self._current_height = 0
else:
self._current_height = self._max_height
if self._animate_id:
gobject.source_remove(self._animate_id)
self._animate_id = gobject.timeout_add(100, self.__do_animation)
def get_image(self):
"@return the gtk.Image widget"
return self._image
def set_image(self, stock):
"Set the image to stock"
self._image.set_from_stock(stock, gtk.ICON_SIZE_MENU)
def get_label(self):
"@return the gtk.Label widget"
return self._label
def set_label(self, txt):
"Set the text to label and restore image to original"
self._label.set_text(txt)
self._label.set_use_markup(self._markup)
self.image = gtk.STOCK_DIALOG_INFO
image = property(get_image, set_image)
label = property(get_label, set_label)
gobject.type_register(HIGAnimatedBar)
if __name__ == "__main__":
w = gtk.Window()
def add(b, v):
anim = HIGAnimatedBar(
"<span font-desc=\"Monospace\"><b>"
"W00t! from stupid animated widget"
"</b></span>"
)
v.pack_start(anim)
anim.show()
vbox = gtk.VBox()
btn = gtk.Button(stock=gtk.STOCK_ADD)
btn.connect('clicked', add, vbox)
bar = HIGAnimatedBar("<b>Hey man try to click! :)</b>")
vbox.pack_start( \
bar, \
False, False, 0
)
vbox.pack_start(btn, False, False, 0)
hbb = gtk.HButtonBox()
btn = gtk.Button("SHOW")
btn.connect('clicked', lambda x, w: w.start_animation(True), bar)
hbb.pack_start(btn)
btn = gtk.Button("HIDE")
btn.connect('clicked', lambda x, w: w.start_animation(False), bar)
hbb.pack_start(btn)
vbox.pack_start(hbb, False, False)
w.add(vbox)
w.set_size_request(200, 200)
w.show_all()
w.connect('delete-event', lambda *w: gtk.main_quit())
gtk.main()
|