### BEGIN LICENSE
# Copyright (C) 2010 Rick Spencer rick.spencer@canonical.com
#This program is free software: you can redistribute it and/or modify it 
#under the terms of the GNU General Public License version 3, as published 
#by the Free Software Foundation.
#
#This program is distributed in the hope that it will be useful, but 
#WITHOUT ANY WARRANTY; without even the implied warranties of 
#MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
### END LICENSE

"""A Button that fires a tick event as long as the user holds it down.
So long as the user is holding down the button, it will fire a tick
event every 250 milliseconds by default.

Using
#create the button and connect to the tick event
pah = PressAndHoldButton()
pah.connect('tick',__handle_on_tick)

def __handle_on_tick(widget, data=None):
    #do something once on each tick

Configuring
#Change the timeout period in milliseconds by adjusting the
#timeout property
pah.timeout = 10000

#set the label as a normal button
pah.set_labe("Press and Hold")

Extending
A PressAndHoldButton is Gtk.Button

"""

from gi.repository import GObject
from gi.repository import Gtk

class PressAndHoldButton(Gtk.Button):
    def __init__(self):
        """Create a PressAndHoldButton

        After creating it, you can change the frequency of the tick
        event by setting timeout property in milliseconds. The default
        timeout period is 250 milliseconds.

        """

        Gtk.Button.__init__(self)
        self.timeout = 250
        self.connect("pressed",self.__pressed)
        self.connect("released",self.__released)
        self.__continue_ticking = True

    def __pressed(self, widget, data=None):
        self.__continue_ticking = True
        widget.emit("tick",self)
        GObject.timeout_add(self.timeout, self.__tick)

    def __released(self, widget, data=None):
        self.__continue_ticking = False

    def __tick(self, data=None):
        if self.__continue_ticking:
            self.emit("tick",self)
        return self.__continue_ticking

    __gsignals__ = {'tick' : (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE,
		(GObject.TYPE_PYOBJECT,)),
		}

def __test_tick(sender, widget, label):
    """internal method for testing.
    Do not use.
    """

    label.set_text(str(int(label.get_text()) + 1))
    


if __name__ == "__main__":
    """creates a test PressAndHoldButton"""

    #create and show a test window
    win = Gtk.Window()
    win.set_title("Press and Hold Test Window")
    win.connect("destroy",Gtk.main_quit)
    win.show()

    #create a top level container
    vbox = Gtk.VBox(False, 10)
    vbox.show()
    win.add(vbox)

    button = PressAndHoldButton()
    button.set_label("Press and hold")
    button.show()
    vbox.pack_start(button, False, False, 5)

    label = Gtk.Label("0")
    label.show()
    vbox.pack_end(label, False, False, 5)

    button.timeout = 10

    button.connect("tick",__test_tick, label)

    Gtk.main()
