Change dependency from gnome.gconf to gconf
[pedometerwidget] / pedometer_widget_home.py
index 5cb6846..6c1a045 100644 (file)
@@ -1,3 +1,19 @@
+#Pedometer Home Widget
+#Author: Mirestean Andrei < andrei.mirestean at 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 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 <http://www.gnu.org/licenses/>.
+
 import gtk
 import cairo
 import hildondesktop
@@ -5,12 +21,7 @@ import gobject
 import os
 import time
 import hildon
-import gnome.gconf as gconf
-from threading import Thread
-
-gobject.threads_init()
-#gtk.gdk.threads_init()
-#print "!!!!"
+import gconf
 
 PATH="/apps/pedometerhomewidget"
 COUNTER=PATH+"/counter"
@@ -102,11 +113,11 @@ class PedoIntervalCounter:
         vals = self.get_best_values(self.x, self.y, self.z)
         return self.count_steps(vals, self.t)
 
-class PedoCounter(Thread):
+class PedoCounter():
     COORD_FNAME = "/sys/class/i2c-adapter/i2c-3/3-001d/coord"
     COORD_FNAME_SDK = "/home/andrei/pedometer-widget-0.1/date.txt"
     LOGFILE = "/home/user/log_pedometer"
-    COORD_GET_INTERVAL = 0.01
+    COORD_GET_INTERVAL = 10
     COUNT_INTERVAL = 5
 
     STEP_LENGTH = 0.7
@@ -118,9 +129,11 @@ class PedoCounter(Thread):
     stop_requested = False
     update_function = None
     logging = False
+    isRunning = False
+
+    mode = 0
 
     def __init__(self, update_function = None):
-        Thread.__init__(self)
         if not os.path.exists(self.COORD_FNAME):
             self.COORD_FNAME = self.COORD_FNAME_SDK
 
@@ -128,6 +141,7 @@ class PedoCounter(Thread):
 
     def set_mode(self, mode):
         #runnig, higher threshold to prevent fake steps
+        self.mode = mode
         if mode == 1:
             self.MIN_THRESHOLD = 650
             self.MIN_TIME_STEPS = 0.35
@@ -142,15 +156,18 @@ class PedoCounter(Thread):
     #set height, will affect the distance
     def set_height(self, height_interval):
         if height_interval == 0:
-            STEP_LENGTH = 0.59
+            self.STEP_LENGTH = 0.59
         elif height_interval == 1:
-            STEP_LENGTH = 0.64
+            self.STEP_LENGTH = 0.64
         elif height_interval == 2:
-            STEP_LENGTH = 0.71
+            self.STEP_LENGTH = 0.71
         elif height_interval == 3:
-            STEP_LENGTH = 0.77
+            self.STEP_LENGTH = 0.77
         elif height_interval == 4:
-            STEP_LENGTH = 0.83
+            self.STEP_LENGTH = 0.83
+        #increase step length if RUNNING
+        if self.mode == 1:
+            self.STEP_LENGTH *= 1.45
 
     def get_rotation(self):
         f = open(self.COORD_FNAME, 'r')
@@ -164,49 +181,62 @@ class PedoCounter(Thread):
     def get_counter(self):
         return counter
 
-    def start_interval(self):
-        logger.info("New interval started")
-        stime = time.time()
-        t=[]
-        coords = [[], [], []]
-        while not self.stop_requested and (len(t) == 0 or t[-1] < 5):
-            x,y,z = self.get_rotation()
-            coords[0].append(int(x))
-            coords[1].append(int(y))
-            coords[2].append(int(z))
-            now = time.time()-stime
-            if self.logging:
-                self.file.write("%d %d %d %f\n" %(coords[0][-1], coords[1][-1], coords[2][-1], now))
-
-            t.append(now)
-            time.sleep(self.COORD_GET_INTERVAL)
-        pic = PedoIntervalCounter(coords, t)
+    def start(self):
+        logger.info("Counter started")
+        self.isRunning = True
+        if self.logging:
+            fname = "%d_%d_%d_%d_%d_%d" % time.localtime()[0:6]
+            self.file = open(self.LOGFILE + fname + ".txt", "w")
+        gobject.idle_add(self.run)
+
+    def run(self):
+        self.coords = [[], [], []]
+        self.stime = time.time()
+        self.t = []
+        gobject.timeout_add(self.COORD_GET_INTERVAL, self.read_coords)
+        return False
+
+    def read_coords(self):
+        x,y,z = self.get_rotation()
+        self.coords[0].append(int(x))
+        self.coords[1].append(int(y))
+        self.coords[2].append(int(z))
+        now = time.time()-self.stime
+        if self.logging:
+            self.file.write("%d %d %d %f\n" %(self.coords[0][-1], self.coords[1][-1], self.coords[2][-1], now))
+
+        self.t.append(now)
+        #call stop_interval
+        ret = True
+        if self.t[-1] > 5 or self.stop_requested:
+            ret = False
+            gobject.idle_add(self.stop_interval)
+        return ret
+
+    def stop_interval(self):
+        pic = PedoIntervalCounter(self.coords, self.t)
         cnt = pic.number_steps()
 
-        logger.info("Number of steps detected for last interval %d, number of coords: %d" % (cnt, len(t)))
+        logger.info("Number of steps detected for last interval %d, number of coords: %d" % (cnt, len(self.t)))
 
         self.counter += cnt
         logger.info("Total number of steps : %d" % self.counter)
-        return cnt
-
-    def request_stop(self):
-        self.stop_requested = True
-
-    def run(self):
-        logger.info("Thread started")
-        if self.logging:
-            fname = "%d_%d_%d_%d_%d_%d" % time.localtime()[0:6]
-            self.file = open(self.LOGFILE + fname + ".txt", "w")
+        gobject.idle_add(self.update_function, self.counter, cnt)
 
-        while 1 and not self.stop_requested:
-            last_cnt = self.start_interval()
-            if self.update_function is not None:
-                gobject.idle_add(self.update_function, self.counter, last_cnt)
+        if self.stop_requested:
+            gobject.idle_add(self.stop)
+        else:
+            gobject.idle_add(self.run)
+        return False
 
+    def stop(self):
         if self.logging:
             self.file.close()
+        logger.info("Counter has finished")
 
-        logger.info("Thread has finished")
+    def request_stop(self):
+        self.stop_requested = True
+        self.isRunning = False
 
     def get_distance(self, steps=None):
         if steps == None:
@@ -260,10 +290,13 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
     button = None
 
     #labels for current steps
-    labelsC = { "timer" : None, "count" : None, "dist" : None, "avgSpeed" : None }
+    labels = ["timer", "count", "dist", "avgSpeed"]
+    #labelsC = { "timer" : None, "count" : None, "dist" : None, "avgSpeed" : None }
 
     #labels for all time steps
-    labelsT = { "timer" : None, "count" : None, "dist" : None, "avgSpeed" : None }
+    #labelsT = { "timer" : None, "count" : None, "dist" : None, "avgSpeed" : None }
+    labelsC = {}
+    labelsT = {}
 
     pedometer = None
     startTime = None
@@ -280,8 +313,6 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
     logging = False
 
     def __init__(self):
-
-        #gtk.gdk.threads_init()
         hildondesktop.HomePluginItem.__init__(self)
 
         self.client = gconf.client_get_default()
@@ -319,14 +350,14 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
         mainHBox = gtk.HBox(spacing=1)
 
         descVBox = gtk.VBox(spacing=1)
-        descVBox.add(gtk.Label())
-        descVBox.add(gtk.Label("Time:"))
-        descVBox.add(gtk.Label("Steps:"))
-        descVBox.add(gtk.Label("Distance:"))
-        descVBox.add(gtk.Label("Avg Speed:"))
+        descVBox.add(self.new_label_heading())
+        descVBox.add(self.new_label_heading("Time:"))
+        descVBox.add(self.new_label_heading("Steps:"))
+        descVBox.add(self.new_label_heading("Distance:"))
+        descVBox.add(self.new_label_heading("Avg Speed:"))
 
         currentVBox = gtk.VBox(spacing=1)
-        currentVBox.add(gtk.Label("Current"))
+        currentVBox.add(self.new_label_heading("Current"))
         currentVBox.add(self.labelsC["timer"])
         currentVBox.add(self.labelsC["count"])
         currentVBox.add(self.labelsC["dist"])
@@ -334,7 +365,7 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
         self.currentBox = currentVBox
 
         totalVBox = gtk.VBox(spacing=1)
-        totalVBox.add(gtk.Label("Total"))
+        totalVBox.add(self.new_label_heading("Total"))
         totalVBox.add(self.labelsT["timer"])
         totalVBox.add(self.labelsT["count"])
         totalVBox.add(self.labelsT["dist"])
@@ -342,9 +373,9 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
         self.totalBox = totalVBox
 
         buttonVBox = gtk.VBox(spacing=1)
-        buttonVBox.add(gtk.Label(""))
+        buttonVBox.add(self.new_label_heading(""))
         buttonVBox.add(self.button)
-        buttonVBox.add(gtk.Label(""))
+        buttonVBox.add(self.new_label_heading(""))
 
         mainHBox.add(buttonVBox)
         mainHBox.add(descVBox)
@@ -361,11 +392,17 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
         self.set_settings(True)
         self.connect("show-settings", self.show_settings)
 
-    def create_labels(self, labels):
-        labels["timer"] = gtk.Label()
-        labels["count"] = gtk.Label()
-        labels["dist"] = gtk.Label()
-        labels["avgSpeed"] = gtk.Label()
+    def new_label_heading(self, title=""):
+        l = gtk.Label(title)
+        hildon.hildon_helper_set_logical_font(l, "SmallSystemFont")
+        return l
+
+    def create_labels(self, new_labels):
+        for label in self.labels:
+            l = gtk.Label()
+            hildon.hildon_helper_set_logical_font(l, "SmallSystemFont")
+            hildon.hildon_helper_set_logical_color(l, gtk.RC_FG, gtk.STATE_NORMAL, "ActiveTextColor")
+            new_labels[label] = l
 
     def update_aspect(self):
         if self.aspect == 0:
@@ -441,10 +478,18 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
         def selector_changed(selector, data):
             widget.mode = selector.get_active(0)
             widget.client.set_int(MODE, widget.mode)
+            widget.pedometer.set_mode(widget.mode)
+            widget.pedometer.set_height(widget.height)
+            widget.update_current()
+            widget.update_total()
 
         def selectorH_changed(selector, data):
             widget.height = selectorH.get_active(0)
             widget.client.set_int(HEIGHT, widget.height)
+            widget.pedometer.set_height(widget.height)
+            widget.update_current()
+            widget.update_total()
+
 
         def selectorUnit_changed(selector, data):
             widget.unit = selectorUnit.get_active(0)
@@ -462,7 +507,6 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
             widget.client.set_bool(LOGGING, widget.logging)
 
         dialog = gtk.Dialog()
-        dialog.set_transient_for(self)
         dialog.set_title("Settings")
 
         dialog.add_button("OK", gtk.RESPONSE_OK)
@@ -529,16 +573,21 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
         logButton.set_active(widget.logging)
         logButton.connect("toggled", logButton_changed)
 
-        dialog.vbox.add(button)
-        dialog.vbox.add(modePicker)
-        dialog.vbox.add(heightPicker)
-        dialog.vbox.add(unitPicker)
-        dialog.vbox.add(UIPicker)
-        dialog.vbox.add(logButton)
-
+        pan_area = hildon.PannableArea()
+        vbox = gtk.VBox()
+        vbox.add(button)
+        vbox.add(modePicker)
+        vbox.add(heightPicker)
+        vbox.add(unitPicker)
+        vbox.add(UIPicker)
+        vbox.add(logButton)
+
+        pan_area.add_with_viewport(vbox)
+        pan_area.set_size_request(-1, 600)
+        dialog.vbox.add(pan_area)
         dialog.show_all()
         response = dialog.run()
-        hildon.hildon_banner_show_information(self, "None", "You have to Stop/Start the counter to apply the new settings")
+        #hildon.hildon_banner_show_information(self, "None", "You have to Stop/Start the counter to apply the new settings")
         dialog.destroy()
 
     def close_requested(self, widget):
@@ -546,8 +595,6 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
             return
 
         self.pedometer.request_stop()
-        if self.pedometer.isAlive():
-            self.pedometer.join()
 
     def update_values(self, totalCurent, lastInterval):
         self.totalCounter += lastInterval
@@ -561,10 +608,9 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
         self.update_total()
 
     def button_clicked(self, button):
-        if self.pedometer is not None and self.pedometer.isAlive():
+        if self.pedometer is not None and self.pedometer.isRunning:
             #counter is running
             self.pedometer.request_stop()
-            self.pedometer.join()
             self.client.set_int(COUNTER, self.totalCounter)
             self.client.set_int(TIMER, int(self.totalTime))
             #self.button.set_label("Start")
@@ -575,7 +621,6 @@ class PedometerHomePlugin(hildondesktop.HomePluginItem):
             self.pedometer.set_height(self.height)
             self.pedometer.set_logging(self.logging)
 
-
             self.time = 0
             self.counter = 0
 
@@ -643,8 +688,6 @@ if __name__ == "__main__":
 import math
 import logging
 
-from threading import Thread
-
 logger = logging.getLogger("pedometer")
 logger.setLevel(logging.INFO)