You Are Here:

Community: Wiki

This page was last modified on 29 September 2009, at 14:47.

How to do virtual arrow keys on Touch UI

From Forum Nokia Wiki

Reviewer Approved   
Reviewer Approved   


ID Creation date August 30, 2009
Platform S60 5th Edition Tested on devices Nokia 5800
Category Python Subcategory Touch


Keywords (APIs, classes, methods, functions): appuifw

Introduction

This PyS60 sample application demonstrates how to use Touch UI as virtual 5-way rocker key using PyS60 1.9.7 release.

The article contains code example demonstrating,

  • How to dynamically divide screen into 5 active areas on-screen
  • How to handle key down and key up events and whether they occurred within same area
  • How to handle touch specific code in non-touch enabled environment

Note: this code has been tested in Nokia 5800 (touch enabled) and S60 3.1 emulator (no touch support)

Code Snippet

Clicking on top horizontal blue bar works like pressing Up Arrow key, bottom horizontal bar like Down Arrow. In the middle there are three vertical bars. First bar works like Left Arrow, second bar like Enter or Return and third bar works like Right Arrow.

Press top bar and look at the dialog. Wait until it disappears and raise your finger on bottom bar. You will see a dialog telling which area you pressed first and which area you lifted your finger.

'''
Touch Stick - Touch UI screen as virtual joystick
 
Copyright (c) 2009 Jouni Miettunen
http://jouni.miettunen.googlepages.com/
 
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 
1.10 2009-08-31 Removed img.clear(RGB_BLACK) as unnecessary
1.00 2009-08-30 Initial release
'
''
 
VERSION = u'1.10'
 
import e32
import appuifw
import graphics
import key_codes
 
# Global variables
TOUCH_ENABLED = False
touch_key = None
canvas = None
img = None
 
def cb_redraw(dummy=(0, 0, 0, 0)):
''' Overwrite default screen redraw event handler '''
if img:
 
x1, y1 = (0, 0)
x4, y4 = canvas.size
x2 = x4 / 3
x3 = 2 * x2
y2 = y4 / 4
y3 = 3 * y2
 
# DEBUG
# print canvas.size
# print x1, x2, x3, x4
# print y1, y2, y3, y4
 
RGB_G1 = (50, 50, 255)
RGB_G2 = (100, 100, 255)
RGB_G3 = (150, 150, 255)
RGB_G4 = (200, 200, 255)
RGB_G5 = (250, 250, 255)
img.rectangle(((x1, y1), (x4, y2)), fill=RGB_G1)
img.rectangle(((x1, y3), (x4, y4)), fill=RGB_G2)
img.rectangle(((x1, y2), (x2, y3)), fill=RGB_G3)
img.rectangle(((x2, y2), (x3, y3)), fill=RGB_G4)
img.rectangle(((x3, y2), (x4, y3)), fill=RGB_G5)
 
canvas.blit(img)
 
def button_text(a_button):
''' Convert button to text '''
if a_button == key_codes.EKeyUpArrow:
s = "Up"
elif a_button == key_codes.EKeyLeftArrow:
s = "Left"
elif a_button == key_codes.EKeyEnter:
s = "Middle"
elif a_button == key_codes.EKeyRightArrow:
s = "Right"
elif a_button == key_codes.EKeyDownArrow:
s = "Down"
else:
s = "Unknown"
return s
 
def cb_up0(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
touch_key = key_codes.EKeyUpArrow
appuifw.note(u"Up button down")
 
def cb_left0(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
touch_key = key_codes.EKeyLeftArrow
appuifw.note(u"Left button down")
 
def cb_enter0(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
touch_key = key_codes.EKeyEnter
appuifw.note(u"Middle button down")
 
def cb_right0(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
touch_key = key_codes.EKeyRightArrow
appuifw.note(u"Right button down")
 
def cb_down0(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
touch_key = key_codes.EKeyDownArrow
appuifw.note(u"Down button down")
 
def cb_up1(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
key = touch_key
touch_key = None
s = "%s button down,\n%s button up" % (button_text(key), "Up")
appuifw.note(unicode(s))
 
def cb_left1(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
key = touch_key
touch_key = None
s = "%s button down,\n%s button up" % (button_text(key), "Left")
appuifw.note(unicode(s))
 
def cb_enter1(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
key = touch_key
touch_key = None
s = "%s button down,\n%s button up" % (button_text(key), "Middle")
appuifw.note(unicode(s))
 
def cb_right1(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
key = touch_key
touch_key = None
s = "%s button down,\n%s button up" % (button_text(key), "Right")
appuifw.note(unicode(s))
 
def cb_down1(pos=(0, 0)):
''' Event handler for touch area '''
global touch_key
key = touch_key
touch_key = None
s = "%s button down,\n%s button up" % (button_text(key), "Down")
appuifw.note(unicode(s))
 
def menu_about():
''' Callback for menu item About '''
appuifw.note(u'TouchStick v' + VERSION +\
u'\n\u00a9 2009 Jouni Miettunen')
 
def cb_quit():
''' About to exit, do clean-up first '''
app_lock.signal()
 
#############################################################
appuifw.app.orientation = 'portrait'
appuifw.app.screen = 'full'
appuifw.app.title = u'TouchStick'
appuifw.app.exit_key_handler = cb_quit
appuifw.app.menu = [
(u"About", menu_about),
(u"Exit", cb_quit)
]
 
if e32.pys60_version_info > (1,9):
appuifw.app.directional_pad = False
if appuifw.touch_enabled():
appuifw.app.screen = 'large'
TOUCH_ENABLED = True
else:
appuifw.note(u"Touch screen not found", "error")
 
canvas = appuifw.Canvas(redraw_callback = cb_redraw)
appuifw.app.body = canvas
img = graphics.Image.new(canvas.size)
 
# Define touchable areas
# HOX: seems like I must define rects in bottom-up order !!!
 
x1, y1 = (0, 0)
x4, y4 = canvas.size
x2 = x4 / 3
x3 = 2 * x2
y2 = y4 / 4
y3 = 3 * y2
 
# Touch screen as virtual on-screen joystick
 
########
 
## ## ##
## ## ##
## ## ##
 
########
 
canvas.bind(key_codes.EButton1Down, cb_down0, ((x1, y3), (x4, y4)))
canvas.bind(key_codes.EButton1Up, cb_down1, ((x1, y3), (x4, y4)))
 
canvas.bind(key_codes.EButton1Down, cb_right0, ((x3, y2), (x4, y3)))
canvas.bind(key_codes.EButton1Up, cb_right1, ((x3, y2), (x4, y3)))
 
canvas.bind(key_codes.EButton1Down, cb_enter0, ((x2, y2), (x3, y3)))
canvas.bind(key_codes.EButton1Up, cb_enter1, ((x2, y2), (x3, y3)))
 
canvas.bind(key_codes.EButton1Down, cb_left0, ((x1, y2), (x2, y3)))
canvas.bind(key_codes.EButton1Up, cb_left1, ((x1, y2), (x2, y3)))
 
canvas.bind(key_codes.EButton1Down, cb_up0, ((x1, y1), (x4, y2)))
canvas.bind(key_codes.EButton1Up, cb_up1, ((x1, y1), (x4, y2)))
 
cb_redraw()
 
#############################################################
if TOUCH_ENABLED:
app_lock = e32.Ao_lock()
app_lock.wait()

Screen shots

File:Touchstick 01.jpg File:Touchstick 02.jpg File:Touchstick 03.jpg

Related Link

How to use touch events with PyS60

PyS60 for 5th Edition + Sample applications

How to check for touch support in Python

Related Wiki Articles

No related wiki articles found

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZidentifierQSxhttpE3aE2fE2fwikiE2eforumE2enokiaE2ecomE2findeE78E2ephpE2fCreatingE5fscreencastsE5fwithE5fmmakerX qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfntypeZCommunityContentQ qdcZtypeQUqfntypeZE52esourceQ qdcZtypeQUqfntypeZWebpageQ qdcZtypeQUqfntypeZWikiContentQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qfnZtopicQUqfnTopicZpythonQ qfnZtopicQUqfnTopicZseriesE5f60Q qfnZtypeQUqfntypeZCommunityContentQ qfnZtypeQUqfntypeZE52esourceQ qfnZtypeQUqfntypeZWebpageQ qfnZtypeQUqfntypeZWikiContentQ qfnZuserE5ftagQSxpythonX qfnZuserE5ftagQSxs60X qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfntypeZCommunityContentQ qrdfZtypeQUqfntypeZE52esourceQ qrdfZtypeQUqfntypeZWebpageQ qrdfZtypeQUqfntypeZWikiContentQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ