SlideShare ist ein Scribd-Unternehmen logo
1 von 7
Downloaden Sie, um offline zu lesen
A Method for More Intelligent Touch Event Processing
Most Likely Widget
Abstract
Touch devices do not provide users with the ability to specify touch event point (x,y)
coordinates with the single-pixel precision of desktop mouse-enabled computers.
The result is that touch device users must tolerate frequent activation of unintended
UI widgets. This slide deck presents a simple, first-draft method for reducing the
frequency of unintended UI widget activation by attempting to infer the most likely
widget which a user intended to activate rather than naively selecting the widget
whose bounding rectangle contains the touch point (x,y) coordinate. Because of the
prevalent Rectangle.contains( Point touchPoint ) based event-to-widget routing
method (perhaps unwisely adopted from desktop systems) missing an intended
widget by a single pixel can sometimes invoke dangerous actions on an unintended
widget such as opening a malicious e-mail when a user's intention was to click an
adjacent selection checkbox so that the suspicious e-mail could be deleted.
Author: Richard Creamer
Website: http://goo.gl/KxGtxQ
Email: 2to32minus1@gmail.com
Copyright © 2012-2014 Richard Creamer - All Rights Reserved
On the right is a mockup of a typical smartphone e-mail
summary app screen. Currently, touch events anywhere
within the green rectangle for that (presumed) table cell will
be sent to the checkbox. Touch events anywhere within the
blue rectangle will cause the e-mail to be displayed.
Even a slight touch positional error such as a touch event in
the first pixel column of the 'E' in Email will invoke an
unintended and perhaps dangerous action (for instance,
opening a malicious e-mail).
In the app mockup to the right, there is a green plus sign at
the centroid for the green checkbox active touch area, and a
blue plus sign in the e-mail summary text area. Ideally, the
red plus sign would be located at the centroid of the
checkbox widget vs. its containing table cell, but this is not
the case on at least one smartphone platform.
The proposed method is based on:
‱ Touch point (x,y) to widget centroid distances
‱ Widget whose bounding rectangle contains (x,y)
‱ Radius of Confusion: A parameterized constant for the
approximate radius of finger touch area/blob in pixels
A simple version of the proposed algorithm:

For each touch event point (x,y)
Determine the widget whose centroid is closest to (x,y)
If this distance is less than the Radius of Confusion:
Map the event to this widget
Else
If no widget centroid is within the Radius of
Confusion distance:
If a widget's bounding rectangle contains (x,y):
Map the event to this widget
Else
Disregard touch event
Note that this is but one simple/illustrative UI context.

 Preferred checkbox widget centroid
 Actual checkbox widget centroid (table cell)
 Email info textbox centroid
Active touch area for checkbox widget
Active touch area for email info textbox area

 Email Sender #1
Email subject blah blah yada yada blah bla...7:37 AM
 First line of email body blah blah yada yada yada blah

blah

Email Sender #2

 Email subject blah blah yada yada blah bla...7:16 AM
First line of email body blah blah yada yada yada blah
blah

Email Sender #3
Email subject blah blah yada yada blah bla...6:42 AM
First line of email body blah blah yada yada yada blah
blah

Email Sender #4
Email subject blah blah yada yada blah bla...6:05 AM
First line of email body blah blah yada yada yada blah
blah
Screenshot of Java/Swing prototype implementation exhaustive test with Radius of Confusion = 40 pixels
On the right is a screenshot of an
exhaustive test harness implementation of
the proposed algorithm.
In the four labeled quadrants:
‱ Upper Left
‱ Ideal case where checkbox widget's
active area is just the checkbox
square (which it is not)
‱ Checkbox and e-mail info area
centroids are marked with uniquelycolored plus signs
‱ Upper Right
‱ Actual case where checkbox widget's
container table cell is the active area
‱ Checkbox cell and e-mail info area
centroids are marked with uniquelycolored plus signs
‱ Lower Left and Lower RIght
‱ At each JPanel pixel, a semitransparent colored pixel was drawn
indicating the widget to which a
touch event at the pixel's (x,y)
coordinates would be mapped
w/proposed algorithm
‱ Both the lower left and right panels
correspond to the panels above
them, respectively

As can be seen, the radius of confusion
parameter can be used to provide the user
with a controllable margin of error in their
touch points.
From this test, it appears that a larger
Radius of Confusion would perform better.
A simple Java implementation of proposed algorithm from prototype code at end of presentation:
///////////////////////////////
// Most Likely Widget Algorithm: (simple implementation)
// 1) Compute closest widget (with closest centroid) to touch point but which is within radiusOfConfusion
// 2) Compute widget rectangle which actually contains touch point
// 3) Route touch event (x,y) to nearest widget if a nearby widget found, else route to widget w/bounding rect containing (x,y)
// Return null if event should not be handled
///////////////////////////////
private static ColoredRect getMostLikelyWidget( int x, int y, List<ColoredRect> widgets, int radiusOfConfusion ) {
int minDist = Integer.MAX_VALUE;
ColoredRect closestWidget = null;
ColoredRect pointInWidget = null;
for ( ColoredRect cr : widgets ) {
Rectangle r = cr.r;
int xc = r.x + r.width/2;
int yc = r.y + r.height/2;
int dist = ( int ) Math.round( Math.sqrt( ( x - xc ) * ( x - xc ) + ( y - yc ) * ( y - yc ) ) );
if ( dist < minDist && dist < radiusOfConfusion ) { // Step 1
minDist = dist;
closestWidget= cr;
}
if ( r.contains( x, y ) ) { // Step 2
pointInWidget = cr;
}
}
return ( closestWidget != null ) ? closestWidget : pointInWidget; // Step 3
}

///////////////////////////////
// Helper class
///////////////////////////////
class ColoredRect {
public final Rectangle r;
public final Color c;
public ColoredRect( Rectangle r, Color c ) {
this.r = r;
this.c = c;
}
} // End class: ColoredRect
Comments

‱The ideas presented herein were inspired by an Android project, Cool Clock,
developed by the author at home a few years ago which needed to enable
elementary grade children to drag graphical analog clock hands without
requiring the touch/drag points to precisely lie within the boundary of each
clock hand. (A similar 'most likely widget' algorithm was developed.)
‱The presented ideas were independently developed. Similarity to other
published works is coincidental and unknown to the author.
‱A wider range of UI contexts should be fully evaluated if this or a similar
algorithm is to be considered for implementation on touch devices for native
apps and browser content.
‱After evaluating a wider range of UI contexts, additional 'most likely widget'
decision metrics, in addition to centroids, may be necessary.
‱It is the opinion of the author that were this or a similar algorithm
implemented, a significant reduction in the amount of user frustration with
touch devices could be achieved.
‱Comments are welcome: 2to32minus1@gmail.com
Simple Java implementation source code (font size = 5 to fit on single slide - intended for copy/past/test/evaluate)
////////////////////////
// Copyright (c) 2014 Richard Creamer - All Rights Reserved
////////////////////////
import java.awt.*;
import java.awt.font.LineMetrics;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.*;

} // End class: Main

drawCheckBox( g2d, r );

///////////////////////////////
// Class which draws a mockup of a smartphone e-mail app
///////////////////////////////

// Compute and save CELL rectangle in which checkbox is contained
r = new Rectangle( x, y, MAIL_TEXT_INSET, PANEL_CELL_HEIGHT );
if ( checkboxCellRects.size() < numEmails )
checkboxCellRects.add( r );

class MockupMailPanel extends JPanel {

if ( mostLikelyWidget != null )
drawAlphaPixel( g2d, x, y, mostLikelyWidget.c );
}
}
}

///////////////////////////////
// Draw email text summary cell...
// Most Likely Widget Algorithm: (simple implementation)
// Static data
// 1) Compute closest widget (with closest centroid) to touch point but which is
private static final int CONTROL_HORIZ_MARGIN = 0;
// First compute cell rectangle containing text
within radiusOfConfusion
private static final int LINE_SEP_HEIGHT = 2;
r = new Rectangle( x + MAIL_TEXT_INSET, y, getWidth() - 2 * CELL_MARGIN,
// 2) Compute widget rectangle which actually contains touch point
///////////////////////////////
private static final int PANEL_CELL_HEIGHT = 95;
PANEL_CELL_HEIGHT );
// 3) Route touch event (x,y) to nearest widget if a nearby widget found, else route
// Main tester class
private static final int VERT_MARGIN = 20; // Gap between top of window and
if ( mailCellRects.size() < numEmails )
to widget w/bounding rect containing (x,y)
///////////////////////////////
beginning of mockup email panel
mailCellRects.add( r );
// Return null if event should not be handled
private static final Color BKG_CLR = new Color( 236, 236, 236 );
///////////////////////////////
public class Main {
private static final Color LINE_DARK_CLR = new Color( 166, 166, 166 );
// Create mockup e-mail header text lines
private static ColoredRect getMostLikelyWidget( int x, int y, List<ColoredRect>
private static final Color LINE_LITE_CLR = new Color( 255, 255, 255 );
String [] textLines = new String [] { "Email Sender #" + ( emailNum + 1 ),
widgets, int radiusOfConfusion ) {
public static void main( String [] args ) {
private static final Color CHECKBOX_LINE_CLR = new Color( 109, 109, 109 );
"Email subject blah blah yada yada blah blah..." +
int minDist = Integer.MAX_VALUE;
SwingUtilities.invokeLater( new Runnable() {
private static final Color CHECKBOX_FILL_CLR = new Color( 201, 201, 201 );
MAIL_TIMES[ emailNum ],
ColoredRect closestWidget = null;
@Override
private static final int CHECKBOX_SIZE = 22;
"First line of email body blah blah blah yada yada
ColoredRect pointInWidget = null;
public void run() {
private static final int CELL_MARGIN = 15;
blah",
for ( ColoredRect cr : widgets ) {
private static final int MAIL_TEXT_INSET = 2 * CELL_MARGIN + CHECKBOX_SIZE;
"blah" };
Rectangle r = cr.r;
// Create e-mail mockup JPanels
private static final String [] MAIL_TIMES = { "7:37 AM", "7:16 AM", "6:42 AM", "6:05
int xc = r.x + r.width/2;
JPanel checkboxCentroidsNoOverlayPanel = makePanelWithInsets( 10, new AM" };
// Draw the text lines for the mockup e-mail
int yc = r.y + r.height/2;
MockupMailPanel( false, false ) );
private static final int numEmails = MAIL_TIMES.length;
int textX = x + MAIL_TEXT_INSET;
int dist = ( int ) Math.round( Math.sqrt( ( x - xc ) * ( x - xc ) + ( y - yc ) * ( y - yc ) )
JPanel checkboxCentroidsWithOverlayPanel = makePanelWithInsets( 10, new private static final Color [] checkboxCentroidColors = { Color.RED, new Color( 0x4a,
int textY = y + CELL_MARGIN;
);
MockupMailPanel( false, true ) );
0xb2, 0x3a ), Color.BLUE, new Color( 0x4a, 0xb2, 0xff ) };
g2d.setColor( Color.BLACK );
if ( dist < minDist && dist < radiusOfConfusion ) { // Step 1
JPanel checkboxCellsNoOverlayPanel = makePanelWithInsets( 10, new
private static final Color [] emailTextAreaCentroidColors = { Color.CYAN,
g2d.setFont( font );
minDist = dist;
MockupMailPanel( true, false ) );
Color.MAGENTA, new Color( 0x9a, 0x6e, 0x04 ), new Color( 0xff, 0x77, 0x04 ) };
FontMetrics fm = getFontMetrics( g2d.getFont() );
closestWidget= cr;
JPanel checkboxCellsWithOverlayPanel = makePanelWithInsets( 10, new
private static final Font font = new Font( "Arial", Font.PLAIN, 16 );
for ( int i = 0; i < textLines.length; ++i ) {
}
MockupMailPanel( true, true ) );
LineMetrics lm = fm.getLineMetrics( textLines[ i ], g2d );
if ( r.contains( x, y ) ) { // Step 2
// Instance data
g2d.drawString( textLines[ i ], textX, textY + lm.getAscent() - 3 ); // The 3 is a
pointInWidget = cr;
// Add titled border inside compound border
private List<Rectangle> checkboxRects = new ArrayList<>();
fudge factor for this quickly hacked code
}
checkboxCentroidsNoOverlayPanel.setBorder( new CompoundBorder( new
private List<Rectangle> checkboxCellRects = new ArrayList<>();
textY += lm.getHeight();
}
TitledBorder( " Mail Mockup Checkbox Centroid - No Overlay " ), new EmptyBorder( 0, private List<Rectangle> mailCellRects = new ArrayList<>();
}
return ( closestWidget != null ) ? closestWidget : pointInWidget; // Step 3
10, 10, 10 ) ) );
private final boolean useCellCentroidsForCheckboxes;
}
}
checkboxCentroidsWithOverlayPanel.setBorder( new CompoundBorder( new private final boolean drawOverlay;
TitledBorder( " Above w/ 'Most Likely Widget' Touch Test Overlay " ), new
///////////////////////////////
///////////////////////////////
EmptyBorder( 0, 10, 10, 10 ) ) );
///////////////////////////////
private void drawCentroids( Graphics2D g2d ) {
private static void drawAlphaPixel( Graphics2D g2d, int x, int y, Color c ) {
checkboxCellsNoOverlayPanel.setBorder( new CompoundBorder( new
public MockupMailPanel( boolean useCellCentroidsForCheckboxes, boolean
int overlayAlpha = 50;
TitledBorder( " Mail Mockup Checkbox Cell Centroid - No Overlay " ), new
drawOverlay ) {
// Draw checkbox centroid crosshairs
g2d.setColor( new Color( c.getRed(), c.getGreen(), c.getBlue(), overlayAlpha ) );
EmptyBorder( 0, 10, 10, 10 ) ) );
this.useCellCentroidsForCheckboxes = useCellCentroidsForCheckboxes;
for ( int i = 0; i < numEmails; ++i ) {
g2d.fillRect( x, y, 1, 1 );
checkboxCellsWithOverlayPanel.setBorder( new CompoundBorder( new
this.drawOverlay = drawOverlay;
Rectangle r = ( useCellCentroidsForCheckboxes ) ? checkboxCellRects.get( i ) :
}
TitledBorder( " Above w/ 'Most Likely Widget' Touch Test Overlay " ), new
}
checkboxRects.get( i );
EmptyBorder( 0, 10, 10, 10 ) ) );
drawCrosshairInRect( g2d, r, checkboxCentroidColors[ i ] );
///////////////////////////////
///////////////////////////////
}
private static void drawCheckBox( Graphics2D g2d, Rectangle r ) {
// Create content pane JPanel
@Override
g2d.setColor( CHECKBOX_FILL_CLR );
JPanel holder = new JPanel();
public void paintComponent( Graphics g ) {
// Draw email text area cell centroid crosshairs
g2d.fillRect( r.x, r.y, r.width, r.height );
holder.setBorder( new EmptyBorder( 10, 10, 10, 10 ) );
Graphics2D g2d = ( Graphics2D ) g;
for ( int i = 0; i < numEmails; ++i ) {
g2d.setColor( CHECKBOX_LINE_CLR );
GridLayout gl = new GridLayout( 2, 2 );
g2d.setRenderingHint( java.awt.RenderingHints.KEY_ANTIALIASING,
Rectangle r = mailCellRects.get( i );
g2d.drawLine( r.x, r.y, r.x + CHECKBOX_SIZE - 1, r.y );
gl.setHgap( 5 );
java.awt.RenderingHints.VALUE_ANTIALIAS_ON );
drawCrosshairInRect( g2d, r, emailTextAreaCentroidColors[ i ] );
g2d.drawLine( r.x, r.y, r.x, r.y + CHECKBOX_SIZE - 1 );
gl.setVgap( 5 );
}
}
holder.setLayout( gl );
g2d.setColor( BKG_CLR );
}
holder.add( checkboxCentroidsNoOverlayPanel );
g2d.fillRect( 0, 0, getWidth(), getHeight() );
///////////////////////////////
holder.add( checkboxCellsNoOverlayPanel );
int x = 0;
///////////////////////////////
private static void drawCrosshairInRect( Graphics2D g2d, Rectangle r, Color c ) {
holder.add( checkboxCentroidsWithOverlayPanel );
int y = VERT_MARGIN;
private void drawMostLikelyWidgetOverlay( Graphics2D g2d ) {
int crosshairRadius = 7;
holder.add( checkboxCellsWithOverlayPanel );
for ( int i = 0; i < numEmails; ++i ) {
int strokeSize = 3;
drawMailEntry( i, g2d, x, y );
// Do not route touch events to widgets farther than this distance
int xc = r.x + r.width/2;
// Create JFrame and add content panel, etc...
y += PANEL_CELL_HEIGHT + 2; // 2 pixels for the separator lines
int radiusOfConfusion = 70;
int yc = r.y + r.height/2;
JFrame jf = new JFrame();
}
g2d.setColor( c );
jf.setContentPane( holder );
drawCentroids( g2d );
// Make single list of special purpose colored rectangle objects to simplify(? ;-) this
g2d.setStroke( new BasicStroke( strokeSize ) );
jf.setSize( 960, 940 ); // 450, 460 );
if ( drawOverlay )
algorithm eval code
g2d.drawLine( xc - crosshairRadius, yc, xc + crosshairRadius, yc );
jf.setResizable( false );
drawMostLikelyWidgetOverlay( g2d );
List<ColoredRect> cr = new ArrayList<>();
g2d.drawLine( xc, yc - crosshairRadius, xc, yc + crosshairRadius );
jf.setTitle( "Most Likely Widget Touch Point Tester" );
}
List<Rectangle> cbRects = ( useCellCentroidsForCheckboxes ) ? checkboxCellRects }
jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
: checkboxRects;
jf.setVisible( true );
///////////////////////////////
for ( int i = 0; i < numEmails; ++i ) {
} // End class: MockupMailPanel
}
private void drawMailEntry( int emailNum, Graphics2D g2d, int x, int y ) {
cr.add( new ColoredRect( cbRects.get( i ), checkboxCentroidColors[ i ] ) );
} );
cr.add( new ColoredRect( mailCellRects.get( i ), emailTextAreaCentroidColors[ i ] ///////////////////////////////
}
// Draw separator lines
) );
// Helper class
g2d.setColor( LINE_DARK_CLR );
}
///////////////////////////////
///////////////////////////////
g2d.drawLine( x, y, getWidth(), y );
private static JPanel makePanelWithInsets( int insetSize, JPanel content ) {
++y;
// Evaluate every pixel in this JPanel-derived class containing mocked up email
final class ColoredRect {
JPanel p = new JPanel();
g2d.setColor( LINE_LITE_CLR );
summary list
public final Rectangle r;
Border margin = BorderFactory.createEmptyBorder( insetSize, insetSize, insetSize,
g2d.drawLine( x, y, getWidth(), y );
int w = getWidth();
public final Color c;
insetSize );
++y;
int h = getHeight();
public ColoredRect( Rectangle r, Color c ) {
p.setBorder( margin );
for ( int i = 0; i < h; ++i ) {
this.r = r;
p.setLayout( new BorderLayout() );
// Draw checkbox and save rectangle for later
int y = i;
this.c = c;
p.add( content, BorderLayout.CENTER );
Rectangle r = new Rectangle( x + CELL_MARGIN, y + CELL_MARGIN,
for ( int j = 0; j < w; ++j ) {
}
return p;
CHECKBOX_SIZE, CHECKBOX_SIZE );
int x = j;
}
if ( checkboxRects.size() < numEmails )
ColoredRect mostLikelyWidget = getMostLikelyWidget( x, y, cr,
} // End class: ColoredRect
checkboxRects.add( r );
radiusOfConfusion );
A Method for More Intelligent Touch Event Processing
Most Likely Widget
Richard Creamer
Website: http://goo.gl/KxGtxQ
Email: 2to32minus1@gmail.com
Copyright © 2012-2014 Richard Creamer - All Rights Reserved

Weitere Àhnliche Inhalte

Andere mochten auch

Look inside OraciĂłn Personal Diaria
Look inside OraciĂłn Personal DiariaLook inside OraciĂłn Personal Diaria
Look inside OraciĂłn Personal DiariaMiguel Mercado
 
¿Por qué crear una Sociedad Laboral?
¿Por qué crear una Sociedad Laboral?¿Por qué crear una Sociedad Laboral?
¿Por qué crear una Sociedad Laboral?ASLE
 
Results on holistic treatment of dermatitis in dogs
Results on holistic treatment of dermatitis in dogs Results on holistic treatment of dermatitis in dogs
Results on holistic treatment of dermatitis in dogs Sergio Canello
 
Jatropha and Sustainable Livelihood of Small-scale Farmers
Jatropha and Sustainable Livelihood of Small-scale FarmersJatropha and Sustainable Livelihood of Small-scale Farmers
Jatropha and Sustainable Livelihood of Small-scale FarmersZK8
 
TechDays 2012 Internet Sites mit SharePoint 2013
TechDays 2012 Internet Sites mit SharePoint 2013TechDays 2012 Internet Sites mit SharePoint 2013
TechDays 2012 Internet Sites mit SharePoint 2013David Schneider
 
ServiceNow Event 15.11.2012 / IT Service Management Franke Artemis Group
ServiceNow Event 15.11.2012 / IT Service Management Franke Artemis GroupServiceNow Event 15.11.2012 / IT Service Management Franke Artemis Group
ServiceNow Event 15.11.2012 / IT Service Management Franke Artemis GroupRené Haeberlin
 
Guia expurgo es
Guia expurgo esGuia expurgo es
Guia expurgo esKatalogador
 
Rossini Equipment
Rossini EquipmentRossini Equipment
Rossini EquipmentRossiniUKLtd
 
Dossier prensa mwc15 v6
Dossier prensa mwc15 v6Dossier prensa mwc15 v6
Dossier prensa mwc15 v6Global InDevices
 
InnovaciĂłn en ciencia y tecnologĂ­a. CĂłmo los investigadores trabajan juntos.
InnovaciĂłn en ciencia y tecnologĂ­a. CĂłmo los investigadores trabajan juntos.InnovaciĂłn en ciencia y tecnologĂ­a. CĂłmo los investigadores trabajan juntos.
InnovaciĂłn en ciencia y tecnologĂ­a. CĂłmo los investigadores trabajan juntos.Simone Belli
 
Revisando condicionales
Revisando condicionalesRevisando condicionales
Revisando condicionaleskarillopart
 
Smart Enterprises
Smart EnterprisesSmart Enterprises
Smart EnterprisesGeorg Guentner
 
Elementos que constituyen la trasmision automatica
Elementos que constituyen la trasmision automaticaElementos que constituyen la trasmision automatica
Elementos que constituyen la trasmision automaticaARMANDO / LUIS
 

Andere mochten auch (16)

Look inside OraciĂłn Personal Diaria
Look inside OraciĂłn Personal DiariaLook inside OraciĂłn Personal Diaria
Look inside OraciĂłn Personal Diaria
 
¿Por qué crear una Sociedad Laboral?
¿Por qué crear una Sociedad Laboral?¿Por qué crear una Sociedad Laboral?
¿Por qué crear una Sociedad Laboral?
 
Results on holistic treatment of dermatitis in dogs
Results on holistic treatment of dermatitis in dogs Results on holistic treatment of dermatitis in dogs
Results on holistic treatment of dermatitis in dogs
 
Jatropha and Sustainable Livelihood of Small-scale Farmers
Jatropha and Sustainable Livelihood of Small-scale FarmersJatropha and Sustainable Livelihood of Small-scale Farmers
Jatropha and Sustainable Livelihood of Small-scale Farmers
 
TechDays 2012 Internet Sites mit SharePoint 2013
TechDays 2012 Internet Sites mit SharePoint 2013TechDays 2012 Internet Sites mit SharePoint 2013
TechDays 2012 Internet Sites mit SharePoint 2013
 
ServiceNow Event 15.11.2012 / IT Service Management Franke Artemis Group
ServiceNow Event 15.11.2012 / IT Service Management Franke Artemis GroupServiceNow Event 15.11.2012 / IT Service Management Franke Artemis Group
ServiceNow Event 15.11.2012 / IT Service Management Franke Artemis Group
 
Buruhandiak
BuruhandiakBuruhandiak
Buruhandiak
 
Guia expurgo es
Guia expurgo esGuia expurgo es
Guia expurgo es
 
Rossini Equipment
Rossini EquipmentRossini Equipment
Rossini Equipment
 
Dossier prensa mwc15 v6
Dossier prensa mwc15 v6Dossier prensa mwc15 v6
Dossier prensa mwc15 v6
 
InnovaciĂłn en ciencia y tecnologĂ­a. CĂłmo los investigadores trabajan juntos.
InnovaciĂłn en ciencia y tecnologĂ­a. CĂłmo los investigadores trabajan juntos.InnovaciĂłn en ciencia y tecnologĂ­a. CĂłmo los investigadores trabajan juntos.
InnovaciĂłn en ciencia y tecnologĂ­a. CĂłmo los investigadores trabajan juntos.
 
Revisando condicionales
Revisando condicionalesRevisando condicionales
Revisando condicionales
 
Presentasjon av Einar Busterud - Anleggskonferansen
Presentasjon av Einar Busterud - AnleggskonferansenPresentasjon av Einar Busterud - Anleggskonferansen
Presentasjon av Einar Busterud - Anleggskonferansen
 
What have you don?
What have you don?What have you don?
What have you don?
 
Smart Enterprises
Smart EnterprisesSmart Enterprises
Smart Enterprises
 
Elementos que constituyen la trasmision automatica
Elementos que constituyen la trasmision automaticaElementos que constituyen la trasmision automatica
Elementos que constituyen la trasmision automatica
 

KĂŒrzlich hochgeladen

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...gurkirankumar98700
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel AraĂșjo
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 

KĂŒrzlich hochgeladen (20)

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 

A Method for More Intelligent Touch Event Processing: Most Likely Widget

  • 1. A Method for More Intelligent Touch Event Processing Most Likely Widget Abstract Touch devices do not provide users with the ability to specify touch event point (x,y) coordinates with the single-pixel precision of desktop mouse-enabled computers. The result is that touch device users must tolerate frequent activation of unintended UI widgets. This slide deck presents a simple, first-draft method for reducing the frequency of unintended UI widget activation by attempting to infer the most likely widget which a user intended to activate rather than naively selecting the widget whose bounding rectangle contains the touch point (x,y) coordinate. Because of the prevalent Rectangle.contains( Point touchPoint ) based event-to-widget routing method (perhaps unwisely adopted from desktop systems) missing an intended widget by a single pixel can sometimes invoke dangerous actions on an unintended widget such as opening a malicious e-mail when a user's intention was to click an adjacent selection checkbox so that the suspicious e-mail could be deleted. Author: Richard Creamer Website: http://goo.gl/KxGtxQ Email: 2to32minus1@gmail.com Copyright © 2012-2014 Richard Creamer - All Rights Reserved
  • 2. On the right is a mockup of a typical smartphone e-mail summary app screen. Currently, touch events anywhere within the green rectangle for that (presumed) table cell will be sent to the checkbox. Touch events anywhere within the blue rectangle will cause the e-mail to be displayed. Even a slight touch positional error such as a touch event in the first pixel column of the 'E' in Email will invoke an unintended and perhaps dangerous action (for instance, opening a malicious e-mail). In the app mockup to the right, there is a green plus sign at the centroid for the green checkbox active touch area, and a blue plus sign in the e-mail summary text area. Ideally, the red plus sign would be located at the centroid of the checkbox widget vs. its containing table cell, but this is not the case on at least one smartphone platform. The proposed method is based on: ‱ Touch point (x,y) to widget centroid distances ‱ Widget whose bounding rectangle contains (x,y) ‱ Radius of Confusion: A parameterized constant for the approximate radius of finger touch area/blob in pixels A simple version of the proposed algorithm: For each touch event point (x,y) Determine the widget whose centroid is closest to (x,y) If this distance is less than the Radius of Confusion: Map the event to this widget Else If no widget centroid is within the Radius of Confusion distance: If a widget's bounding rectangle contains (x,y): Map the event to this widget Else Disregard touch event Note that this is but one simple/illustrative UI context.  Preferred checkbox widget centroid  Actual checkbox widget centroid (table cell)  Email info textbox centroid Active touch area for checkbox widget Active touch area for email info textbox area  Email Sender #1 Email subject blah blah yada yada blah bla...7:37 AM  First line of email body blah blah yada yada yada blah  blah Email Sender #2  Email subject blah blah yada yada blah bla...7:16 AM First line of email body blah blah yada yada yada blah blah Email Sender #3 Email subject blah blah yada yada blah bla...6:42 AM First line of email body blah blah yada yada yada blah blah Email Sender #4 Email subject blah blah yada yada blah bla...6:05 AM First line of email body blah blah yada yada yada blah blah
  • 3. Screenshot of Java/Swing prototype implementation exhaustive test with Radius of Confusion = 40 pixels On the right is a screenshot of an exhaustive test harness implementation of the proposed algorithm. In the four labeled quadrants: ‱ Upper Left ‱ Ideal case where checkbox widget's active area is just the checkbox square (which it is not) ‱ Checkbox and e-mail info area centroids are marked with uniquelycolored plus signs ‱ Upper Right ‱ Actual case where checkbox widget's container table cell is the active area ‱ Checkbox cell and e-mail info area centroids are marked with uniquelycolored plus signs ‱ Lower Left and Lower RIght ‱ At each JPanel pixel, a semitransparent colored pixel was drawn indicating the widget to which a touch event at the pixel's (x,y) coordinates would be mapped w/proposed algorithm ‱ Both the lower left and right panels correspond to the panels above them, respectively As can be seen, the radius of confusion parameter can be used to provide the user with a controllable margin of error in their touch points. From this test, it appears that a larger Radius of Confusion would perform better.
  • 4. A simple Java implementation of proposed algorithm from prototype code at end of presentation: /////////////////////////////// // Most Likely Widget Algorithm: (simple implementation) // 1) Compute closest widget (with closest centroid) to touch point but which is within radiusOfConfusion // 2) Compute widget rectangle which actually contains touch point // 3) Route touch event (x,y) to nearest widget if a nearby widget found, else route to widget w/bounding rect containing (x,y) // Return null if event should not be handled /////////////////////////////// private static ColoredRect getMostLikelyWidget( int x, int y, List<ColoredRect> widgets, int radiusOfConfusion ) { int minDist = Integer.MAX_VALUE; ColoredRect closestWidget = null; ColoredRect pointInWidget = null; for ( ColoredRect cr : widgets ) { Rectangle r = cr.r; int xc = r.x + r.width/2; int yc = r.y + r.height/2; int dist = ( int ) Math.round( Math.sqrt( ( x - xc ) * ( x - xc ) + ( y - yc ) * ( y - yc ) ) ); if ( dist < minDist && dist < radiusOfConfusion ) { // Step 1 minDist = dist; closestWidget= cr; } if ( r.contains( x, y ) ) { // Step 2 pointInWidget = cr; } } return ( closestWidget != null ) ? closestWidget : pointInWidget; // Step 3 } /////////////////////////////// // Helper class /////////////////////////////// class ColoredRect { public final Rectangle r; public final Color c; public ColoredRect( Rectangle r, Color c ) { this.r = r; this.c = c; } } // End class: ColoredRect
  • 5. Comments ‱The ideas presented herein were inspired by an Android project, Cool Clock, developed by the author at home a few years ago which needed to enable elementary grade children to drag graphical analog clock hands without requiring the touch/drag points to precisely lie within the boundary of each clock hand. (A similar 'most likely widget' algorithm was developed.) ‱The presented ideas were independently developed. Similarity to other published works is coincidental and unknown to the author. ‱A wider range of UI contexts should be fully evaluated if this or a similar algorithm is to be considered for implementation on touch devices for native apps and browser content. ‱After evaluating a wider range of UI contexts, additional 'most likely widget' decision metrics, in addition to centroids, may be necessary. ‱It is the opinion of the author that were this or a similar algorithm implemented, a significant reduction in the amount of user frustration with touch devices could be achieved. ‱Comments are welcome: 2to32minus1@gmail.com
  • 6. Simple Java implementation source code (font size = 5 to fit on single slide - intended for copy/past/test/evaluate) //////////////////////// // Copyright (c) 2014 Richard Creamer - All Rights Reserved //////////////////////// import java.awt.*; import java.awt.font.LineMetrics; import java.util.List; import java.util.ArrayList; import javax.swing.*; import javax.swing.border.*; } // End class: Main drawCheckBox( g2d, r ); /////////////////////////////// // Class which draws a mockup of a smartphone e-mail app /////////////////////////////// // Compute and save CELL rectangle in which checkbox is contained r = new Rectangle( x, y, MAIL_TEXT_INSET, PANEL_CELL_HEIGHT ); if ( checkboxCellRects.size() < numEmails ) checkboxCellRects.add( r ); class MockupMailPanel extends JPanel { if ( mostLikelyWidget != null ) drawAlphaPixel( g2d, x, y, mostLikelyWidget.c ); } } } /////////////////////////////// // Draw email text summary cell... // Most Likely Widget Algorithm: (simple implementation) // Static data // 1) Compute closest widget (with closest centroid) to touch point but which is private static final int CONTROL_HORIZ_MARGIN = 0; // First compute cell rectangle containing text within radiusOfConfusion private static final int LINE_SEP_HEIGHT = 2; r = new Rectangle( x + MAIL_TEXT_INSET, y, getWidth() - 2 * CELL_MARGIN, // 2) Compute widget rectangle which actually contains touch point /////////////////////////////// private static final int PANEL_CELL_HEIGHT = 95; PANEL_CELL_HEIGHT ); // 3) Route touch event (x,y) to nearest widget if a nearby widget found, else route // Main tester class private static final int VERT_MARGIN = 20; // Gap between top of window and if ( mailCellRects.size() < numEmails ) to widget w/bounding rect containing (x,y) /////////////////////////////// beginning of mockup email panel mailCellRects.add( r ); // Return null if event should not be handled private static final Color BKG_CLR = new Color( 236, 236, 236 ); /////////////////////////////// public class Main { private static final Color LINE_DARK_CLR = new Color( 166, 166, 166 ); // Create mockup e-mail header text lines private static ColoredRect getMostLikelyWidget( int x, int y, List<ColoredRect> private static final Color LINE_LITE_CLR = new Color( 255, 255, 255 ); String [] textLines = new String [] { "Email Sender #" + ( emailNum + 1 ), widgets, int radiusOfConfusion ) { public static void main( String [] args ) { private static final Color CHECKBOX_LINE_CLR = new Color( 109, 109, 109 ); "Email subject blah blah yada yada blah blah..." + int minDist = Integer.MAX_VALUE; SwingUtilities.invokeLater( new Runnable() { private static final Color CHECKBOX_FILL_CLR = new Color( 201, 201, 201 ); MAIL_TIMES[ emailNum ], ColoredRect closestWidget = null; @Override private static final int CHECKBOX_SIZE = 22; "First line of email body blah blah blah yada yada ColoredRect pointInWidget = null; public void run() { private static final int CELL_MARGIN = 15; blah", for ( ColoredRect cr : widgets ) { private static final int MAIL_TEXT_INSET = 2 * CELL_MARGIN + CHECKBOX_SIZE; "blah" }; Rectangle r = cr.r; // Create e-mail mockup JPanels private static final String [] MAIL_TIMES = { "7:37 AM", "7:16 AM", "6:42 AM", "6:05 int xc = r.x + r.width/2; JPanel checkboxCentroidsNoOverlayPanel = makePanelWithInsets( 10, new AM" }; // Draw the text lines for the mockup e-mail int yc = r.y + r.height/2; MockupMailPanel( false, false ) ); private static final int numEmails = MAIL_TIMES.length; int textX = x + MAIL_TEXT_INSET; int dist = ( int ) Math.round( Math.sqrt( ( x - xc ) * ( x - xc ) + ( y - yc ) * ( y - yc ) ) JPanel checkboxCentroidsWithOverlayPanel = makePanelWithInsets( 10, new private static final Color [] checkboxCentroidColors = { Color.RED, new Color( 0x4a, int textY = y + CELL_MARGIN; ); MockupMailPanel( false, true ) ); 0xb2, 0x3a ), Color.BLUE, new Color( 0x4a, 0xb2, 0xff ) }; g2d.setColor( Color.BLACK ); if ( dist < minDist && dist < radiusOfConfusion ) { // Step 1 JPanel checkboxCellsNoOverlayPanel = makePanelWithInsets( 10, new private static final Color [] emailTextAreaCentroidColors = { Color.CYAN, g2d.setFont( font ); minDist = dist; MockupMailPanel( true, false ) ); Color.MAGENTA, new Color( 0x9a, 0x6e, 0x04 ), new Color( 0xff, 0x77, 0x04 ) }; FontMetrics fm = getFontMetrics( g2d.getFont() ); closestWidget= cr; JPanel checkboxCellsWithOverlayPanel = makePanelWithInsets( 10, new private static final Font font = new Font( "Arial", Font.PLAIN, 16 ); for ( int i = 0; i < textLines.length; ++i ) { } MockupMailPanel( true, true ) ); LineMetrics lm = fm.getLineMetrics( textLines[ i ], g2d ); if ( r.contains( x, y ) ) { // Step 2 // Instance data g2d.drawString( textLines[ i ], textX, textY + lm.getAscent() - 3 ); // The 3 is a pointInWidget = cr; // Add titled border inside compound border private List<Rectangle> checkboxRects = new ArrayList<>(); fudge factor for this quickly hacked code } checkboxCentroidsNoOverlayPanel.setBorder( new CompoundBorder( new private List<Rectangle> checkboxCellRects = new ArrayList<>(); textY += lm.getHeight(); } TitledBorder( " Mail Mockup Checkbox Centroid - No Overlay " ), new EmptyBorder( 0, private List<Rectangle> mailCellRects = new ArrayList<>(); } return ( closestWidget != null ) ? closestWidget : pointInWidget; // Step 3 10, 10, 10 ) ) ); private final boolean useCellCentroidsForCheckboxes; } } checkboxCentroidsWithOverlayPanel.setBorder( new CompoundBorder( new private final boolean drawOverlay; TitledBorder( " Above w/ 'Most Likely Widget' Touch Test Overlay " ), new /////////////////////////////// /////////////////////////////// EmptyBorder( 0, 10, 10, 10 ) ) ); /////////////////////////////// private void drawCentroids( Graphics2D g2d ) { private static void drawAlphaPixel( Graphics2D g2d, int x, int y, Color c ) { checkboxCellsNoOverlayPanel.setBorder( new CompoundBorder( new public MockupMailPanel( boolean useCellCentroidsForCheckboxes, boolean int overlayAlpha = 50; TitledBorder( " Mail Mockup Checkbox Cell Centroid - No Overlay " ), new drawOverlay ) { // Draw checkbox centroid crosshairs g2d.setColor( new Color( c.getRed(), c.getGreen(), c.getBlue(), overlayAlpha ) ); EmptyBorder( 0, 10, 10, 10 ) ) ); this.useCellCentroidsForCheckboxes = useCellCentroidsForCheckboxes; for ( int i = 0; i < numEmails; ++i ) { g2d.fillRect( x, y, 1, 1 ); checkboxCellsWithOverlayPanel.setBorder( new CompoundBorder( new this.drawOverlay = drawOverlay; Rectangle r = ( useCellCentroidsForCheckboxes ) ? checkboxCellRects.get( i ) : } TitledBorder( " Above w/ 'Most Likely Widget' Touch Test Overlay " ), new } checkboxRects.get( i ); EmptyBorder( 0, 10, 10, 10 ) ) ); drawCrosshairInRect( g2d, r, checkboxCentroidColors[ i ] ); /////////////////////////////// /////////////////////////////// } private static void drawCheckBox( Graphics2D g2d, Rectangle r ) { // Create content pane JPanel @Override g2d.setColor( CHECKBOX_FILL_CLR ); JPanel holder = new JPanel(); public void paintComponent( Graphics g ) { // Draw email text area cell centroid crosshairs g2d.fillRect( r.x, r.y, r.width, r.height ); holder.setBorder( new EmptyBorder( 10, 10, 10, 10 ) ); Graphics2D g2d = ( Graphics2D ) g; for ( int i = 0; i < numEmails; ++i ) { g2d.setColor( CHECKBOX_LINE_CLR ); GridLayout gl = new GridLayout( 2, 2 ); g2d.setRenderingHint( java.awt.RenderingHints.KEY_ANTIALIASING, Rectangle r = mailCellRects.get( i ); g2d.drawLine( r.x, r.y, r.x + CHECKBOX_SIZE - 1, r.y ); gl.setHgap( 5 ); java.awt.RenderingHints.VALUE_ANTIALIAS_ON ); drawCrosshairInRect( g2d, r, emailTextAreaCentroidColors[ i ] ); g2d.drawLine( r.x, r.y, r.x, r.y + CHECKBOX_SIZE - 1 ); gl.setVgap( 5 ); } } holder.setLayout( gl ); g2d.setColor( BKG_CLR ); } holder.add( checkboxCentroidsNoOverlayPanel ); g2d.fillRect( 0, 0, getWidth(), getHeight() ); /////////////////////////////// holder.add( checkboxCellsNoOverlayPanel ); int x = 0; /////////////////////////////// private static void drawCrosshairInRect( Graphics2D g2d, Rectangle r, Color c ) { holder.add( checkboxCentroidsWithOverlayPanel ); int y = VERT_MARGIN; private void drawMostLikelyWidgetOverlay( Graphics2D g2d ) { int crosshairRadius = 7; holder.add( checkboxCellsWithOverlayPanel ); for ( int i = 0; i < numEmails; ++i ) { int strokeSize = 3; drawMailEntry( i, g2d, x, y ); // Do not route touch events to widgets farther than this distance int xc = r.x + r.width/2; // Create JFrame and add content panel, etc... y += PANEL_CELL_HEIGHT + 2; // 2 pixels for the separator lines int radiusOfConfusion = 70; int yc = r.y + r.height/2; JFrame jf = new JFrame(); } g2d.setColor( c ); jf.setContentPane( holder ); drawCentroids( g2d ); // Make single list of special purpose colored rectangle objects to simplify(? ;-) this g2d.setStroke( new BasicStroke( strokeSize ) ); jf.setSize( 960, 940 ); // 450, 460 ); if ( drawOverlay ) algorithm eval code g2d.drawLine( xc - crosshairRadius, yc, xc + crosshairRadius, yc ); jf.setResizable( false ); drawMostLikelyWidgetOverlay( g2d ); List<ColoredRect> cr = new ArrayList<>(); g2d.drawLine( xc, yc - crosshairRadius, xc, yc + crosshairRadius ); jf.setTitle( "Most Likely Widget Touch Point Tester" ); } List<Rectangle> cbRects = ( useCellCentroidsForCheckboxes ) ? checkboxCellRects } jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); : checkboxRects; jf.setVisible( true ); /////////////////////////////// for ( int i = 0; i < numEmails; ++i ) { } // End class: MockupMailPanel } private void drawMailEntry( int emailNum, Graphics2D g2d, int x, int y ) { cr.add( new ColoredRect( cbRects.get( i ), checkboxCentroidColors[ i ] ) ); } ); cr.add( new ColoredRect( mailCellRects.get( i ), emailTextAreaCentroidColors[ i ] /////////////////////////////// } // Draw separator lines ) ); // Helper class g2d.setColor( LINE_DARK_CLR ); } /////////////////////////////// /////////////////////////////// g2d.drawLine( x, y, getWidth(), y ); private static JPanel makePanelWithInsets( int insetSize, JPanel content ) { ++y; // Evaluate every pixel in this JPanel-derived class containing mocked up email final class ColoredRect { JPanel p = new JPanel(); g2d.setColor( LINE_LITE_CLR ); summary list public final Rectangle r; Border margin = BorderFactory.createEmptyBorder( insetSize, insetSize, insetSize, g2d.drawLine( x, y, getWidth(), y ); int w = getWidth(); public final Color c; insetSize ); ++y; int h = getHeight(); public ColoredRect( Rectangle r, Color c ) { p.setBorder( margin ); for ( int i = 0; i < h; ++i ) { this.r = r; p.setLayout( new BorderLayout() ); // Draw checkbox and save rectangle for later int y = i; this.c = c; p.add( content, BorderLayout.CENTER ); Rectangle r = new Rectangle( x + CELL_MARGIN, y + CELL_MARGIN, for ( int j = 0; j < w; ++j ) { } return p; CHECKBOX_SIZE, CHECKBOX_SIZE ); int x = j; } if ( checkboxRects.size() < numEmails ) ColoredRect mostLikelyWidget = getMostLikelyWidget( x, y, cr, } // End class: ColoredRect checkboxRects.add( r ); radiusOfConfusion );
  • 7. A Method for More Intelligent Touch Event Processing Most Likely Widget Richard Creamer Website: http://goo.gl/KxGtxQ Email: 2to32minus1@gmail.com Copyright © 2012-2014 Richard Creamer - All Rights Reserved