[Sugar-devel] [PATCH 1/3] Touchpad extension for the frame
--- extensions/deviceicon/touchpad.py | 152 + 1 files changed, 152 insertions(+), 0 deletions(-) create mode 100644 extensions/deviceicon/touchpad.py diff --git a/extensions/deviceicon/touchpad.py b/extensions/deviceicon/touchpad.py new file mode 100644 index 000..a182d9c --- /dev/null +++ b/extensions/deviceicon/touchpad.py @@ -0,0 +1,152 @@ +# Copyright (C) 2010, Walter Bender, Sugar Labs +# +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +from gettext import gettext as _ + +import gtk +import gconf +from os import system, path, remove + +from sugar.graphics.tray import TrayIcon +from sugar.graphics.xocolor import XoColor +from sugar.graphics.palette import Palette +from jarabe.frame.frameinvoker import FrameWidgetInvoker + +_STATUS_TEXT = {'capacitive': _('finger'), 'resistive': _('stylus')} +_CAPACITIVE_ICON_NAME = 'touchpad-capacitive' +_RESISTIVE_ICON_NAME = 'touchpad-resistive' +_FLAG_PATH = '/home/olpc/.olpc-pentablet-mode' +_NODE_PATH = '/sys/devices/platform/i8042/serio1/ptmode' + + +class DeviceView(TrayIcon): +""" Manage the touchpad mode from the device palette on the Frame """ + +FRAME_POSITION_RELATIVE = 500 + +def __init__(self): +""" Create the touchpad palette and display it on Frame """ + +# Only appears when the device exisits +if not path.exists(_NODE_PATH): +return + +if get_touchpad() == 'resistive': +icon_name = _RESISTIVE_ICON_NAME +else: +icon_name = _CAPACITIVE_ICON_NAME + +client = gconf.client_get_default() +color = XoColor(client.get_string('/desktop/sugar/user/color')) +TrayIcon.__init__(self, icon_name=icon_name, xo_color=color) +self.set_palette_invoker(FrameWidgetInvoker(self)) +self.connect('button-release-event', self.__button_release_event_cb) +self.connect('expose-event', self.__expose_event_cb) + +def create_palette(self): +""" On create, set the current mode """ +self.palette = ResourcePalette(_('My touchpad'), self.icon) +self.palette.set_group_id('frame') +return self.palette + +def __button_release_event_cb(self, widget, event): +""" On button release, switch modes """ +self.palette.toggle_mode() +return True + +def __expose_event_cb(self, *args): +pass + + +class ResourcePalette(Palette): +""" Query the current state of the touchpad and update the display """ + +def __init__(self, primary_text, icon): +""" Get the status """ +Palette.__init__(self, label=primary_text) + +self._icon = icon + +self.connect('popup', self.__popup_cb) +self.connect('popdown', self.__popdown_cb) + +self.updating = False + +vbox = gtk.VBox() +self.set_content(vbox) + +self._status_text = gtk.Label() +vbox.pack_start(self._status_text, padding=10) +self._status_text.show() + +vbox.show() + +self._mode = get_touchpad() +self.set_mode_graphics() + +def set_mode_graphics(self): +""" Set the label and icon based on the current mode """ +self._status_text.set_label(_STATUS_TEXT[self._mode]) +if self._mode == 'resistive': +self._icon.props.icon_name = _RESISTIVE_ICON_NAME +else: +self._icon.props.icon_name = _CAPACITIVE_ICON_NAME + +def toggle_mode(self): +""" On mouse click, toggle the mode """ +if self._mode == 'capacitive': +self._mode = 'resistive' +else: +self._mode = 'capacitive' + +set_touchpad(self._mode) +self.set_mode_graphics() + +def __popup_cb(self, gobject): +self.updating = True + +def __popdown_cb(self, gobject): +self.updating = False + + +def setup(tray): +tray.add_device(DeviceView()) + + +def get_touchpad(): +""" Get the touchpad mode. """ +_file_handle = open(_NODE_PATH, "r") +_text = _file_handle.read() +_file_handle.close() + +if _text[0] == '1': +return 'resistive' +else: +return 'capacitive' + + +def set_touchpad(touchpad): +""" Set the touchpad mode. """ +if touchpad == 'capacitive': +if path.exists(_FLAG_PATH): +remove(_
Re: [Sugar-devel] [PATCH 1/3] Touchpad extension for the frame
On 8 Jul 2010, at 17:23, Walter Bender wrote: > --- > extensions/deviceicon/touchpad.py | 152 + > 1 files changed, 152 insertions(+), 0 deletions(-) > create mode 100644 extensions/deviceicon/touchpad.py > > diff --git a/extensions/deviceicon/touchpad.py > b/extensions/deviceicon/touchpad.py > new file mode 100644 > index 000..a182d9c > --- /dev/null > +++ b/extensions/deviceicon/touchpad.py > @@ -0,0 +1,152 @@ > +# Copyright (C) 2010, Walter Bender, Sugar Labs > +# > +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + > + > +from gettext import gettext as _ > + > +import gtk > +import gconf > +from os import system, path, remove The os import should be in the first block. I wouldn't import the methods, prepending os. to the actual calls makes it clearer what the methods are doing. > +from sugar.graphics.tray import TrayIcon > +from sugar.graphics.xocolor import XoColor > +from sugar.graphics.palette import Palette > +from jarabe.frame.frameinvoker import FrameWidgetInvoker > + The jarabe import should be in a separate block. > +_STATUS_TEXT = {'capacitive': _('finger'), 'resistive': _('stylus')} > +_CAPACITIVE_ICON_NAME = 'touchpad-capacitive' > +_RESISTIVE_ICON_NAME = 'touchpad-resistive' > +_FLAG_PATH = '/home/olpc/.olpc-pentablet-mode' > +_NODE_PATH = '/sys/devices/platform/i8042/serio1/ptmode' I think we don't need to mark these has private, the plugins code is not imported by other modules, so private/public doesn't matter. > + > + One less new line :) I'm sure everyone has been missing my nitpicks! > +class DeviceView(TrayIcon): > +""" Manage the touchpad mode from the device palette on the Frame """ > + > +FRAME_POSITION_RELATIVE = 500 > + > +def __init__(self): > +""" Create the touchpad palette and display it on Frame """ > + > +# Only appears when the device exisits > +if not path.exists(_NODE_PATH): > +return > + Aborting constructions looks wrong, better to move the check to the setup method. > +if get_touchpad() == 'resistive': > +icon_name = _RESISTIVE_ICON_NAME > +else: > +icon_name = _CAPACITIVE_ICON_NAME It would be nice to use a dictionary like you did with the label. > + > +client = gconf.client_get_default() > +color = XoColor(client.get_string('/desktop/sugar/user/color')) > +TrayIcon.__init__(self, icon_name=icon_name, xo_color= Splitting the blocks with a new line here would be more readable. > +self.set_palette_invoker(FrameWidgetInvoker(self)) > +self.connect('button-release-event', self.__button_release_event_cb) > +self.connect('expose-event', self.__expose_event_cb) > + > +def create_palette(self): > +""" On create, set the current mode """ > +self.palette = ResourcePalette(_('My touchpad'), self.icon) > +self.palette.set_group_id('frame') > +return self.palette > + > +def __button_release_event_cb(self, widget, event): > +""" On button release, switch modes """ > +self.palette.toggle_mode() > +return True > + > +def __expose_event_cb(self, *args): > +pass > Leftover? Seems unnecessary to connect the signal since you are just passing then. > + > +class ResourcePalette(Palette): > +""" Query the current state of the touchpad and update the display """ > + > +def __init__(self, primary_text, icon): > +""" Get the status """ > +Palette.__init__(self, label=primary_text) > + > +self._icon = icon > + > +self.connect('popup', self.__popup_cb) > +self.connect('popdown', self.__popdown_cb) > + > +self.updating = False > + > +vbox = gtk.VBox() > +self.set_content(vbox) > + > +self._status_text = gtk.Label() > +vbox.pack_start(self._status_text, padding=10) > +self._status_text.show() > + > +vbox.show() > + > +self._mode = get_touchpad() > +self.set_mode_graphics() > + > +def set_mode_graphics(self): Looks like this can be marked as private? update would be more appropriate then set since you are not passing a mode. > +""" Set the label and icon based on the current mode """ > +self._status_text
Re: [Sugar-devel] [PATCH 1/3] Touchpad extension for the frame
In general, this looks olpc specific right now, but I think it's fine to have it upstream, we can abstract it more later if we need to support different hardware. It's a while I don't code or review Sugar patches so I might very well be missing things... And I can't really test the patch right now. Thanks! Marco ___ Sugar-devel mailing list Sugar-devel@lists.sugarlabs.org http://lists.sugarlabs.org/listinfo/sugar-devel
Re: [Sugar-devel] [PATCH 1/3] Touchpad extension for the frame
Marco, It is a real pleasure to have you reengaged. Thanks for the feedback. regards. -walter On Thu, Jul 8, 2010 at 7:26 PM, Marco Pesenti Gritti wrote: > In general, this looks olpc specific right now, but I think it's fine to have > it upstream, we can abstract it more later if we need to support different > hardware. > > It's a while I don't code or review Sugar patches so I might very well be > missing things... And I can't really test the patch right now. > > Thanks! > Marco -- Walter Bender Sugar Labs http://www.sugarlabs.org ___ Sugar-devel mailing list Sugar-devel@lists.sugarlabs.org http://lists.sugarlabs.org/listinfo/sugar-devel
Re: [Sugar-devel] [PATCH 1/3] Touchpad extension for the frame
From my recent experience of getting a similar patch reviewed, I have the following additional feedback :-) > + vbox.pack_start(self._status_text, padding=10) The padding shouldn't be hardcoded to a number of pixels, see the constants in style.py. (maybe padding=style.DEFAULT_PADDING?) > +def get_touchpad(): > + """ Get the touchpad mode. """ > + _file_handle = open(_NODE_PATH, "r") > + _text = _file_handle.read() > + _file_handle.close() Maybe put this is a try... block? > + if touchpad == 'capacitive': > + if path.exists(_FLAG_PATH): > + remove(_FLAG_PATH) > + system("echo 0 > %s" % (_NODE_PATH)) > + else: > + _file_handle = open(_FLAG_PATH, "w") > + _file_handle.close() > + system("echo 1 > %s" % (_NODE_PATH)) > + return Tomeu will nag you about "" vs. '' in the system(...) calls ;) ___ Sugar-devel mailing list Sugar-devel@lists.sugarlabs.org http://lists.sugarlabs.org/listinfo/sugar-devel
Re: [Sugar-devel] [PATCH 1/3] Touchpad extension for the frame
I think I addressed all of the issues raised by Marco and Anish: --- extensions/deviceicon/touchpad.py | 129 + 1 files changed, 129 insertions(+), 0 deletions(-) create mode 100644 extensions/deviceicon/touchpad.py diff --git a/extensions/deviceicon/touchpad.py b/extensions/deviceicon/touchpad.py new file mode 100644 index 000..a182d9c --- /dev/null +++ b/extensions/deviceicon/touchpad.py @@ -0,0 +1,129 @@ +# Copyright (C) 2010, Walter Bender, Sugar Labs +# +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +from gettext import gettext as _ + +import gtk +import gconf +import os + +from sugar.graphics.tray import TrayIcon +from sugar.graphics.xocolor import XoColor +from sugar.graphics.palette import Palette +from sugar.graphics import style + +from jarabe.frame.frameinvoker import FrameWidgetInvoker + +TOUCHPAD_MODES = ['capacitive', 'resistive'] +STATUS_TEXT = {TOUCHPAD_MODES[0]: _('finger'), TOUCHPAD_MODES[1]: _('stylus')} +STATUS_ICON = {TOUCHPAD_MODES[0]: 'touchpad-' + TOUCHPAD_MODES[0], + TOUCHPAD_MODES[1]: 'touchpad-' + TOUCHPAD_MODES[1]} +# FLAG_PATH is used to preserve status between boots. +FLAG_PATH = '/home/olpc/.olpc-pentablet-mode' +# NODE_PATH is used to communicate with the touchpad device. +NODE_PATH = '/sys/devices/platform/i8042/serio1/ptmode' + +class DeviceView(TrayIcon): +""" Manage the touchpad mode from the device palette on the Frame. """ + +FRAME_POSITION_RELATIVE = 500 + +def __init__(self): +""" Create the touchpad palette and display it on Frame. """ +icon_name = STATUS_ICON[read_touchpad_mode()] + +client = gconf.client_get_default() +color = XoColor(client.get_string('/desktop/sugar/user/color')) +TrayIcon.__init__(self, icon_name=icon_name, xo_color=color) + +self.set_palette_invoker(FrameWidgetInvoker(self)) +self.connect('button-release-event', self.__button_release_event_cb) + +def create_palette(self): +""" On create, set the current mode """ +self.palette = ResourcePalette(_('My touchpad'), self.icon) +self.palette.set_group_id('frame') +return self.palette + +def __button_release_event_cb(self, widget, event): +""" On button release, switch modes """ +self.palette.toggle_mode() +return True + + +class ResourcePalette(Palette): +""" Query the current state of the touchpad and update the display. """ + +def __init__(self, primary_text, icon): +""" Get the status. """ +Palette.__init__(self, label=primary_text) + +self._icon = icon + +vbox = gtk.VBox() +self.set_content(vbox) + +self._status_text = gtk.Label() +vbox.pack_start(self._status_text, padding=style.DEFAULT_PADDING) +self._status_text.show() + +vbox.show() + +self._mode = read_touchpad_mode() +self._update() + +def _update(self): +""" Update the label and icon based on the current mode. """ +self._status_text.set_label(STATUS_TEXT[self._mode]) +self._icon.props.icon_name = STATUS_ICON[self._mode] + +def toggle_mode(self): +""" On mouse click, toggle the mode. """ +self._mode = TOUCHPAD_MODES[1 - TOUCHPAD_MODES.index(self._mode)] +write_touchpad_mode(self._mode) +self._update() + + +def setup(tray): +""" Only appears when the device exisits """ +if os.path.exists(NODE_PATH): +tray.add_device(DeviceView()) + + +def read_touchpad_mode(): +""" Read the touchpad mode from the node path. """ +node_file_handle = open(NODE_PATH, "r") +text = node_file_handle.read() +node_file_handle.close() + +return TOUCHPAD_MODES[int(text[0])] + + +def write_touchpad_mode(touchpad): +""" Write the touchpad mode to the node path. """ +touchpad_mode_index = TOUCHPAD_MODES.index(touchpad) + +node_file_handle = open(NODE_PATH, "w") +node_file_handle.write(str(touchpad_mode_index)) +node_file_handle.close() + +if touchpad_mode_index == 0: +if os.path.exists(FLAG_PATH): +os.remove(FLAG_PATH) +else: +flag_file_handle = open(FLAG_PATH, "w") +flag_file_handle.close() -walter On Thu, Jul 8, 2010 at 7:19 PM, Marco Pesenti Gritti wrote: > On 8 J
Re: [Sugar-devel] [PATCH 1/3] Touchpad extension for the frame
On 9 Jul 2010, at 05:58, Walter Bender wrote: > +from gettext import gettext as _ > + > +import gtk > +import gconf > +import os Move the os import to the first block :) Nice work! Marco ___ Sugar-devel mailing list Sugar-devel@lists.sugarlabs.org http://lists.sugarlabs.org/listinfo/sugar-devel
Re: [Sugar-devel] [PATCH 1/3] Touchpad extension for the frame
> +def read_touchpad_mode(): > + """ Read the touchpad mode from the node path. """ > + node_file_handle = open(NODE_PATH, "r") > + text = node_file_handle.read() > + node_file_handle.close() > + > + > +def write_touchpad_mode(touchpad): > + """ Write the touchpad mode to the node path. """ > + touchpad_mode_index = TOUCHPAD_MODES.index(touchpad) > + > + node_file_handle = open(NODE_PATH, "w") > + node_file_handle.write(str(touchpad_mode_index)) > + node_file_handle.close() ... > + > + if touchpad_mode_index == 0: > + if os.path.exists(FLAG_PATH): > + os.remove(FLAG_PATH) > + else: > + flag_file_handle = open(FLAG_PATH, "w") > + flag_file_handle.close() Maybe s/"w"/'w'/ and s/"r"/'r'/ ;-) ? I missed reporting this earlier. On Fri, Jul 9, 2010 at 10:28 AM, Walter Bender wrote: > I think I addressed all of the issues raised by Marco and Anish: > > --- > extensions/deviceicon/touchpad.py | 129 > + > 1 files changed, 129 insertions(+), 0 deletions(-) > create mode 100644 extensions/deviceicon/touchpad.py > > diff --git a/extensions/deviceicon/touchpad.py > b/extensions/deviceicon/touchpad.py > new file mode 100644 > index 000..a182d9c > --- /dev/null > +++ b/extensions/deviceicon/touchpad.py > @@ -0,0 +1,129 @@ > +# Copyright (C) 2010, Walter Bender, Sugar Labs > +# > +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > + > + > +from gettext import gettext as _ > + > +import gtk > +import gconf > +import os > + > +from sugar.graphics.tray import TrayIcon > +from sugar.graphics.xocolor import XoColor > +from sugar.graphics.palette import Palette > +from sugar.graphics import style > + > +from jarabe.frame.frameinvoker import FrameWidgetInvoker > + > +TOUCHPAD_MODES = ['capacitive', 'resistive'] > +STATUS_TEXT = {TOUCHPAD_MODES[0]: _('finger'), TOUCHPAD_MODES[1]: > _('stylus')} > +STATUS_ICON = {TOUCHPAD_MODES[0]: 'touchpad-' + TOUCHPAD_MODES[0], > + TOUCHPAD_MODES[1]: 'touchpad-' + TOUCHPAD_MODES[1]} > +# FLAG_PATH is used to preserve status between boots. > +FLAG_PATH = '/home/olpc/.olpc-pentablet-mode' > +# NODE_PATH is used to communicate with the touchpad device. > +NODE_PATH = '/sys/devices/platform/i8042/serio1/ptmode' > + > +class DeviceView(TrayIcon): > + """ Manage the touchpad mode from the device palette on the Frame. """ > + > + FRAME_POSITION_RELATIVE = 500 > + > + def __init__(self): > + """ Create the touchpad palette and display it on Frame. """ > + icon_name = STATUS_ICON[read_touchpad_mode()] > + > + client = gconf.client_get_default() > + color = XoColor(client.get_string('/desktop/sugar/user/color')) > + TrayIcon.__init__(self, icon_name=icon_name, xo_color=color) > + > + self.set_palette_invoker(FrameWidgetInvoker(self)) > + self.connect('button-release-event', self.__button_release_event_cb) > + > + def create_palette(self): > + """ On create, set the current mode """ > + self.palette = ResourcePalette(_('My touchpad'), self.icon) > + self.palette.set_group_id('frame') > + return self.palette > + > + def __button_release_event_cb(self, widget, event): > + """ On button release, switch modes """ > + self.palette.toggle_mode() > + return True > + > + > +class ResourcePalette(Palette): > + """ Query the current state of the touchpad and update the display. """ > + > + def __init__(self, primary_text, icon): > + """ Get the status. """ > + Palette.__init__(self, label=primary_text) > + > + self._icon = icon > + > + vbox = gtk.VBox() > + self.set_content(vbox) > + > + self._status_text = gtk.Label() > + vbox.pack_start(self._status_text, padding=style.DEFAULT_PADDING) > + self._status_text.show() > + > + vbox.show() > + > + self._mode = read_touchpad_mode() > + self._update() > + > + def _update(self): > + """ Update the label and icon based on the current mode. """ > + self._status_text.set_label(STATUS_TEXT[self._mode]) > + self._icon.props.icon_name = STATUS_ICON[self._mode] > + > + def toggle_mode(self): > + """ On mouse click, toggle the mode. """ > +