All credit for this goes to:
http://www.linux.com/community/blogs/n900-desktop-widget-lucid-dreaming-reality-check.html
So, do a
apt-get install hildon-desktop-python-loader python-hildondesktop
Add a file /usr/share/applications/hildon-home/realitycheck.desktop (download)
[Desktop Entry]
Name=Reality Check
Comment=Reality Check, used to help induce a lucid dreaming and simply vibrates to remind you to do a reality check
Type=python
X-Path=realitycheck.py
X-Multiple=true
Add a file /usr/lib/hildon-desktop/realitycheck.py (download)
#!/usr/bin/env python
import os
import gtk
import glib
import osso #high end interface to dbus
import cairo#vector graphic drawing library
import hildon
import hildondesktop
from gtk import Window, Button, Widget, Image
#apt-get install hildon-desktop-python-loader
#apt-get install pythonhildon-desktop
#apt-get install hildon-desktop-python-loader
class realityCheckWidget(hildondesktop.HomePluginItem):
#applications settings
config_path='/home/user/.realitycheck'
vibrate=True
vibrateRepeat=15
def __init__(self):
hildondesktop.HomePluginItem.__init__(self)
self.load()
#enable the settings button, and function to call on click
self.set_settings(True)
self.connect("show-settings", self.show_options)
#the vibrate timeout callback
if self.vibrate==True:
self.timeout_handler = glib.timeout_add_seconds(60*self.vibrateRepeat, self.vibratePhone)
#request size of area to render text into.
self.set_size_request(660,200)
#draw scene
def draw_cairo(self, cr): # This currently doesn't work
#set cairo surface for drawing we require an alpha layer
cr.set_source_rgba(1.0, 1.0, 1.0, 0.0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
#choose font and style ie bold italic
cr.select_font_face("tahoma", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD);
#set the font size
cr.set_font_size(60);
#font colour, position and text
cr.set_source_rgb(65535,65535,65535)
cr.move_to(20, 50);
cr.show_text("Are you dreaming ?");
#second line of text use text path so we can have a fill and stroke
cr.set_source_rgb(0,0,0)
cr.move_to(20, 120);
cr.text_path("Reality Check")
cr.fill_preserve()
cr.set_source_rgb(65535,65535,65535)
cr.stroke()
#default option selection
def show_options(self, widget):
APP_TITLE="Reality Check"
dialog = gtk.Dialog("Reality Check Options", None, gtk.DIALOG_DESTROY_WITH_PARENT)
#add settings button to dialog
settings_button = hildon.Button(gtk.HILDON_SIZE_HALFSCREEN_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
settings_button.set_text("Settings", "Change the frequency")
settings_button.set_alignment(0,0,0,0)
settings_button.connect('clicked', self.show_settings)
#add license button to dialog
about_button = hildon.Button(gtk.HILDON_SIZE_HALFSCREEN_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
about_button.set_text("About", "More about Author, Copyright and License")
about_button.set_alignment(0,0,0,0)
about_button.connect("clicked", self.show_about)
#pad the buttons into a box for nice alignment
hboxRow = gtk.HBox()
hboxRow.pack_start(settings_button, True, True, 0)
hboxRow.pack_start(about_button, True, True, 0)
#add button row to the dialog and display it
dialog.vbox.pack_start(hboxRow, True, True, 0)
dialog.show_all()
dialog.run()
dialog.destroy()
#Setup the settings UI , store changed parameters
def show_settings(self, widget):
#create a dialog and attach our buttons to the dialog
dialog = gtk.Dialog("Settings", None, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR)
btnSave = dialog.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_OK)
main_vbox = gtk.VBox()
ts = hildon.TouchSelector()
ts.add(main_vbox)
#create the options and labels
btn0mins = hildon.GtkRadioButton(gtk.HILDON_SIZE_HALFSCREEN_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, None)
btn0mins.set_label("1 Min")
btn0mins.set_mode(False)
btn1mins = hildon.GtkRadioButton(gtk.HILDON_SIZE_HALFSCREEN_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, btn0mins)
btn1mins.set_label("15 Mins")
btn1mins.set_mode(False)
btn2mins = hildon.GtkRadioButton(gtk.HILDON_SIZE_HALFSCREEN_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, btn1mins)
btn2mins.set_label("30 Mins")
btn2mins.set_mode(False)
btn3mins = hildon.GtkRadioButton(gtk.HILDON_SIZE_HALFSCREEN_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, btn1mins)
btn3mins.set_label("1 Hours")
btn3mins.set_mode(False)
btn4mins = hildon.GtkRadioButton(gtk.HILDON_SIZE_HALFSCREEN_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, btn1mins)
btn4mins.set_label("2 Hours")
btn4mins.set_mode(False)
#toggle vibrate on and off
btnVibrate = hildon.GtkToggleButton(gtk.HILDON_SIZE_HALFSCREEN_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT)
btnVibrate.set_label("Vibrate")
btnVibrate.set_mode(False)
#what options are currently set, highlight the currently active options
if self.vibrateRepeat == 1:
btn0mins.set_active(True)
elif self.vibrateRepeat == 15:
btn1mins.set_active(True)
elif self.vibrateRepeat == 30:
btn2mins.set_active(True)
elif self.vibrateRepeat == 60:
btn3mins.set_active(True)
elif self.vibrateRepeat == 120:
btn4mins.set_active(True)
else:
btn1mins.set_active(True) #Fallback
if self.vibrate==True:
btnVibrate.set_active(True)
#pack the buttons into a horizontal box
hBoxLayout = gtk.HBox()
hBoxLayout.pack_start(btn0mins, True, True, 0)
hBoxLayout.pack_start(btn1mins, True, True, 0)
hBoxLayout.pack_start(btn2mins, True, True, 0)
hBoxLayout.pack_start(btn3mins, True, True, 0)
hBoxLayout.pack_start(btn4mins, True, True, 0)
hBoxLayout.pack_end(btnVibrate, True, True, 0)
main_vbox.pack_start(hBoxLayout, True, True, 10)
dialog.vbox.add(ts)
dialog.show_all()
response = dialog.run()
#Parse the updated settings
if response == gtk.RESPONSE_OK:
camera_buttons = btn1mins.get_group()
self.vibrate=btnVibrate.get_active()
for button in camera_buttons:
selected = button.get_active()
if selected == True:
label=button.get_label()
if label=='1 Min':
self.vibrateRepeat=1
if label=='15 Mins':
self.vibrateRepeat=15
if label=='30 Mins':
self.vibrateRepeat=30
if label=='1 Hours':
self.vibrateRepeat=60
if label=='2 Hours':
self.vibrateRepeat=120
#clear vibrate event and rest if we need to
if hasattr(self,'timeout_handler'):
glib.source_remove(self.timeout_handler)
if self.vibrate==True:
self.timeout_handler = glib.timeout_add_seconds(60*self.vibrateRepeat, self.vibratePhone)
dialog.destroy()
self.save()
#Show the about dialog
def show_about(self, widget):
dialog = gtk.AboutDialog()
dialog.set_title("About")
dialog.set_name('Reality Check')
dialog.set_version('1.0')
dialog.set_copyright("Copyright 2010 Oliver Marks")
dialog.set_authors(["Oliver Marks ",""])
dialog.set_comments("All logos and trademarks are property of their respective owners and are used for informational purposes only.")
dialog.set_license("""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 3 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, see
.""")
dialog.set_wrap_license(True)
#display the license information dialog
dialog.show_all()
dialog.run()
dialog.destroy()
#save settings file
def save(self):
fp = open(self.config_path,'w')
if self.vibrate==True:
fp.write('vibrate:on')
else:
fp.write('vibrate:off')
fp.write('mins:'+str(self.vibrateRepeat)+"")
fp.close()
#load settings file
def load(self):
if not os.path.exists(self.config_path):
fp=open(self.config_path,'w')
fp.write('')
fp.close()
fp = open(self.config_path)
for line in fp.readlines():
sp=line.strip('').split(':')
if sp[0]=='vibrate':
if sp[1]=='on':
self.vibrate=True
else:
self.vibrate=False
if sp[0]=='mins':
self.vibrateRepeat=int(sp[1])
fp.close()
#draw scene when re recieve an expose event ie the scene needs redrawing
def do_expose_event(self, event):
cr = self.window.cairo_create()
cr.rectangle(event.area.x, event.area.y,event.area.width, event.area.height)
cr.clip()
self.draw_cairo(cr)
#setup screen so we can draw on it with cairo
def do_realize(self):
screen = self.get_screen()
self.set_colormap(screen.get_rgba_colormap())
self.set_app_paintable(True)
hildondesktop.HomePluginItem.do_realize(self)
#this code will cause the led on the phone to flash
def led_flash(self):
_ENABLE_LED = 'req_led_pattern_activate'
_DISABLE_LED = 'req_led_pattern_deactivate'
_LED_PATTERN = 'PatternCommunicationIM'
rpc.rpc_run(_MCE_SERVICE, _MCE_REQUEST_PATH,_MCE_REQUEST_IF,_ENABLE_LED,rpc_args=(_LED_PATTERN,"",""),use_system_bus=True)
return True
#cause the phone to vibrate
def vibratePhone(self):
osso_c = osso.Context("osso_test_app", "0.0.1", False)
_MCE_SERVICE = 'com.nokia.mce'
_MCE_REQUEST_PATH = '/com/nokia/mce/request'
_MCE_REQUEST_IF = 'com.nokia.mce.request'
_VIBRATE = 'req_vibrator_pattern_activate'
_VIBRATE_PATTERN= 'PatternChatAndEmail'
rpc = osso.Rpc(osso_c)
rpc.rpc_run(_MCE_SERVICE, _MCE_REQUEST_PATH,_MCE_REQUEST_IF,_VIBRATE,rpc_args=(_VIBRATE_PATTERN,"",""),use_system_bus=True)
return True
hd_plugin_type = realityCheckWidget
# Allow the widget to run on its own, without the hildon desktop loader
if __name__ == "__main__":
import gobject
gobject.type_register(realityCheckWidget)
obj = gobject.new(realityCheckWidget, plugin_id="plugin_id")
obj.show_all()
gtk.main()
Thats it, install the widget.