diff options
author | Thomas Martitz <kugel@rockbox.org> | 2010-11-10 15:25:15 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2010-11-10 15:25:15 +0000 |
commit | 33af0dec28cf31be0ce7195b90546861efcce76f (patch) | |
tree | f106c9118c9191bff00e1468c98540787081c0e8 | |
parent | e134021e1b05f797cffd28c6b4ee72a963ff3812 (diff) |
Touchscreen: Improved scroll threshold
Remove the hardcoded (and way too small) scroll threshold (the distance moved in pixels before we think the users wants to scroll) and replace it with something based on the actual DPI of the screen.
On Android we call the API for that, on other touchscreens we reimplemented Android's formula (as of 2.2) and calculate it.
Flyspray: 11727
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28548 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | android/src/org/rockbox/RockboxFramebuffer.java | 19 | ||||
-rw-r--r-- | apps/gui/bitmap/list.c | 12 | ||||
-rw-r--r-- | firmware/drivers/touchscreen.c | 31 | ||||
-rw-r--r-- | firmware/export/config/cowond2.h | 1 | ||||
-rw-r--r-- | firmware/export/config/mrobe500.h | 2 | ||||
-rw-r--r-- | firmware/export/config/ondavx747.h | 1 | ||||
-rw-r--r-- | firmware/export/config/ondavx767.h | 7 | ||||
-rw-r--r-- | firmware/export/config/ondavx777.h | 1 | ||||
-rw-r--r-- | firmware/export/config/sim.h | 1 | ||||
-rw-r--r-- | firmware/export/lcd.h | 10 | ||||
-rw-r--r-- | firmware/export/touchscreen.h | 1 | ||||
-rw-r--r-- | firmware/target/hosted/android/lcd-android.c | 26 | ||||
-rw-r--r-- | firmware/target/hosted/sdl/lcd-sdl.c | 6 |
13 files changed, 115 insertions, 3 deletions
diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java index 0a60182502..8c99725e7d 100644 --- a/android/src/org/rockbox/RockboxFramebuffer.java +++ b/android/src/org/rockbox/RockboxFramebuffer.java @@ -28,16 +28,20 @@ import org.rockbox.Helper.MediaButtonReceiver; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.util.DisplayMetrics; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import android.view.ViewConfiguration; public class RockboxFramebuffer extends View { private Bitmap btm; private ByteBuffer native_buf; private MediaButtonReceiver media_monitor; + private final DisplayMetrics metrics; + private final ViewConfiguration view_config; public RockboxFramebuffer(Context c, int lcd_width, int lcd_height, ByteBuffer native_fb) @@ -53,6 +57,9 @@ public class RockboxFramebuffer extends View media_monitor.register(); /* the service needs to know the about us */ ((RockboxService)c).set_fb(this); + + metrics = c.getResources().getDisplayMetrics(); + view_config = ViewConfiguration.get(c); } public void onDraw(Canvas c) @@ -132,6 +139,18 @@ public class RockboxFramebuffer extends View break; } } + + @SuppressWarnings("unused") + private int getDpi() + { + return metrics.densityDpi; + } + + @SuppressWarnings("unused") + private int getScrollThreshold() + { + return view_config.getScaledTouchSlop(); + } private native void set_lcd_active(int active); private native void touchHandler(boolean down, int x, int y); diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c index 26e15e7978..268209e1c1 100644 --- a/apps/gui/bitmap/list.c +++ b/apps/gui/bitmap/list.c @@ -486,16 +486,26 @@ void _gui_synclist_stop_kinetic_scrolling(void) * otherwise it returns true even if it didn't actually scroll, * but scrolling mode shouldn't be changed **/ + + +static int scroll_begin_threshold; +static int threshold_accumulation; static bool swipe_scroll(struct gui_synclist * gui_list, int line_height, int difference) { /* fixme */ const enum screen_type screen = screens[SCREEN_MAIN].screen_type; const int nb_lines = viewport_get_nb_lines(&list_text[screen]); + if (UNLIKELY(scroll_begin_threshold == 0)) + scroll_begin_threshold = touchscreen_get_scroll_threshold(); + /* make selecting items easier */ - if (abs(difference) < SCROLL_BEGIN_THRESHOLD && scroll_mode == SCROLL_NONE) + threshold_accumulation += abs(difference); + if (threshold_accumulation < scroll_begin_threshold && scroll_mode == SCROLL_NONE) return false; + threshold_accumulation = 0; + /* does the list even scroll? if no, return but still show * the caller that we would scroll */ if (nb_lines >= gui_list->nb_items) diff --git a/firmware/drivers/touchscreen.c b/firmware/drivers/touchscreen.c index 9660e0cb9d..823c2e7a92 100644 --- a/firmware/drivers/touchscreen.c +++ b/firmware/drivers/touchscreen.c @@ -25,6 +25,7 @@ #include "touchscreen.h" #include "string.h" #include "logf.h" +#include "lcd.h" /* Size of the 'dead zone' around each 3x3 button */ #define BUTTON_MARGIN_X (int)(LCD_WIDTH * 0.03) @@ -167,3 +168,33 @@ enum touchscreen_mode touchscreen_get_mode(void) { return current_mode; } + + +#if ((CONFIG_PLATFORM & PLATFORM_ANDROID) == 0) +/* android has an API for this */ + +#define TOUCH_SLOP 16u +#define REFERENCE_DPI 160 + +int touchscreen_get_scroll_threshold(void) +{ +#ifdef LCD_DPI + const int dpi = LCD_DPI; +#else + const int dpi = lcd_get_dpi(); +#endif + + /* Inspired by Android calculation + * + * float density = real dpi / reference dpi (=160) + * int threshold = (int) (density * TOUCH_SLOP + 0.5f);(original calculation) + * + * + 0.5f is for rounding, we use fixed point math to achieve that + */ + + int result = dpi * (TOUCH_SLOP<<1) / REFERENCE_DPI; + result += result & 1; /* round up if needed */ + return result>>1; +} + +#endif diff --git a/firmware/export/config/cowond2.h b/firmware/export/config/cowond2.h index f9de2768bd..ebaa636ac7 100644 --- a/firmware/export/config/cowond2.h +++ b/firmware/export/config/cowond2.h @@ -75,6 +75,7 @@ /* LCD dimensions */ #define LCD_WIDTH 320 #define LCD_HEIGHT 240 +#define LCD_DPI 160 #define LCD_DEPTH 16 #define LCD_PIXELFORMAT 565 diff --git a/firmware/export/config/mrobe500.h b/firmware/export/config/mrobe500.h index 9a201951fc..776b0315f8 100644 --- a/firmware/export/config/mrobe500.h +++ b/firmware/export/config/mrobe500.h @@ -87,9 +87,11 @@ #if _RESOLUTION == _LCD_RES_VGA #define LCD_NATIVE_WIDTH 480 #define LCD_NATIVE_HEIGHT 640 +#define LCD_DPI 216 #else #define LCD_NATIVE_WIDTH 240 #define LCD_NATIVE_HEIGHT 320 +#define LCD_DPI 108 #endif /* choose the lcd orientation. CONFIG_ORIENTATION defined in config.h */ diff --git a/firmware/export/config/ondavx747.h b/firmware/export/config/ondavx747.h index ae80cac562..1cd9143965 100644 --- a/firmware/export/config/ondavx747.h +++ b/firmware/export/config/ondavx747.h @@ -79,6 +79,7 @@ #define LCD_WIDTH 240 #define LCD_HEIGHT 400 #endif +#define LCD_DPI 155 #define LCD_DEPTH 16 /* 16bit colours */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ diff --git a/firmware/export/config/ondavx767.h b/firmware/export/config/ondavx767.h index 19bb7ed580..bf9aaed7c1 100644 --- a/firmware/export/config/ondavx767.h +++ b/firmware/export/config/ondavx767.h @@ -65,8 +65,11 @@ /* LCD dimensions */ #define CONFIG_LCD LCD_ONDAVX767 -#define LCD_WIDTH 320 -#define LCD_HEIGHT 240 +/* this are not actually the correct dimensions (480x272 is correct) + * should be fixed once there's a working LCD driver */ +#define LCD_WIDTH 480 +#define LCD_HEIGHT 272 +#define LCD_DPI 128 #define LCD_DEPTH 16 /* 16bit colours */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ diff --git a/firmware/export/config/ondavx777.h b/firmware/export/config/ondavx777.h index a2ad15533a..b6e7546590 100644 --- a/firmware/export/config/ondavx777.h +++ b/firmware/export/config/ondavx777.h @@ -73,6 +73,7 @@ #define LCD_WIDTH 240 #define LCD_HEIGHT 400 #endif +#define LCD_DPI 155 #define LCD_DEPTH 16 /* 16bit colours */ #define LCD_PIXELFORMAT RGB565 /* rgb565 */ diff --git a/firmware/export/config/sim.h b/firmware/export/config/sim.h index 066201ad08..fc7996e813 100644 --- a/firmware/export/config/sim.h +++ b/firmware/export/config/sim.h @@ -19,6 +19,7 @@ #undef HAVE_ATA_POWER_OFF #undef CONFIG_LCD +#undef LCD_DPI /* likely to be too different on a PC */ #undef CONFIG_LED diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 79231d198e..e6e19b1597 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -549,4 +549,14 @@ extern void lcd_bitmap_transparent(const fb_data *src, int x, int y, #endif /* HAVE_LCD_BITMAP */ + +#ifdef HAVE_TOUCHSCREEN +/* only needed for touchscreen for now, feel free to implement it for others + * once needed + */ + +/* returns the pixel density of the display */ +extern int lcd_get_dpi(void); +#endif + #endif /* __LCD_H__ */ diff --git a/firmware/export/touchscreen.h b/firmware/export/touchscreen.h index 7d1eb4ac8a..a27e60c653 100644 --- a/firmware/export/touchscreen.h +++ b/firmware/export/touchscreen.h @@ -50,5 +50,6 @@ void touchscreen_set_mode(enum touchscreen_mode mode); enum touchscreen_mode touchscreen_get_mode(void); void touchscreen_disable_mapping(void); void touchscreen_reset_mapping(void); +int touchscreen_get_scroll_threshold(void); #endif /* __TOUCHSCREEN_INCLUDE_H_ */ diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c index 78b1f12f7f..f4ef7b5e75 100644 --- a/firmware/target/hosted/android/lcd-android.c +++ b/firmware/target/hosted/android/lcd-android.c @@ -35,6 +35,8 @@ static jmethodID java_lcd_update; static jmethodID java_lcd_update_rect; static bool display_on; +static int dpi; +static int scroll_threshold; void lcd_init_device(void) { @@ -77,6 +79,20 @@ void lcd_init_device(void) RockboxFramebuffer_class, "java_lcd_update_rect", "(IIII)V"); + + jmethodID get_dpi = e->GetMethodID(env_ptr, + RockboxFramebuffer_class, + "getDpi", "()I"); + + jmethodID get_scroll_threshold + = e->GetMethodID(env_ptr, + RockboxFramebuffer_class, + "getScrollThreshold", "()I"); + + dpi = e->CallIntMethod(env_ptr, RockboxFramebuffer_instance, + get_dpi); + scroll_threshold = e->CallIntMethod(env_ptr, RockboxFramebuffer_instance, + get_scroll_threshold); display_on = true; } @@ -101,6 +117,16 @@ bool lcd_active(void) return display_on; } +int lcd_get_dpi(void) +{ + return dpi; +} + +int touchscreen_get_scroll_threshold(void) +{ + return scroll_threshold; +} + /* * (un)block lcd updates. * diff --git a/firmware/target/hosted/sdl/lcd-sdl.c b/firmware/target/hosted/sdl/lcd-sdl.c index 15e4ba95c3..96b1a04aa6 100644 --- a/firmware/target/hosted/sdl/lcd-sdl.c +++ b/firmware/target/hosted/sdl/lcd-sdl.c @@ -111,3 +111,9 @@ void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end, SDL_SetPalette(surface, SDL_LOGPAL|SDL_PHYSPAL, palette, first, steps); } +int lcd_get_dpi(void) +{ + /* TODO: find a way to query it from the OS, SDL doesn't support it + * directly; for now assume the more or less standard 96 */ + return 96; +} |