Hi all,

Attached to this mail is a small patch I wrote a while ago, introducing
border interactions. It quite simply hacks in a 15px magical border
which when tapped induces certain actions:
  * upper border: page up;
  * lower border: page down;
  * left border: history back;
  * right border: history forward.

I've added page up & down because it reads far faster and scrolling
(at least on my wikireader) turned out to be quite unreadable. History
back and forward are handy shortcuts while clicking through links of an
article.

-Tim

>From b10b2a9fbd6e91910f1f0012520f9cbcbc987c91 Mon Sep 17 00:00:00 2001
From: Tim Besard <tim.bes...@gmail.com
Date: Sat, 28 Nov 2009 16:37:35 +0100
Subject: [PATCH] Border interactions (history navigation and page up/down).

---
 wiki-app/history.c      |   39 +++++++++++++++---
 wiki-app/history.h      |    7 ++-
 wiki-app/lcd_buf_draw.c |  101 +++++++++++++++++++++++++++++++++++-----------
 wiki-app/lcd_buf_draw.h |    3 +
 wiki-app/wikilib.c      |   23 ++++++++++-
 5 files changed, 140 insertions(+), 33 deletions(-)

diff --git a/wiki-app/history.c b/wiki-app/history.c
index 7548b06..d6ebef7 100644
--- a/wiki-app/history.c
+++ b/wiki-app/history.c
@@ -44,6 +44,7 @@ int history_count = 0;
 int rendered_history_count = -1;
 int history_changed = HISTORY_SAVE_NONE;
 extern int display_mode;
+int history_index = 0;
 
 static inline unsigned int history_modulus(int modulus) {
 	return modulus % HISTORY_MAX_DISPLAY_ITEM;
@@ -55,10 +56,14 @@ void history_reload()
 	render_history_with_pcf();
 }
 
-void history_add(const long idx_article, const char *title, int b_keep_pos)
+void history_add(const long idx_article, const char *title, int b_keep_pos, int b_shift)
 {
 	int i = 0;
 	int bFound = 0;
+	
+	if (b_shift)
+		history_shift(history_index);
+	history_index = 0;
 
 	history_changed = HISTORY_SAVE_NORMAL;
 	while (!bFound && i < history_count)
@@ -89,11 +94,23 @@ void history_add(const long idx_article, const char *title, int b_keep_pos)
 	history_count++;
 }
 
-void history_log_y_pos(const long y_pos)
-{
-	if (history_changed != HISTORY_SAVE_NORMAL)
-		history_changed = HISTORY_SAVE_POWER_OFF;
-	history_list[0].last_y_pos = y_pos;
+long history_get_article() {
+	return history_list[history_index].idx_article;	
+}
+
+void history_shift(int amount) {
+	if (amount <= 0)
+		return;
+	if (amount >= history_count) {
+		history_clear();
+		return;
+	}
+	history_count -= amount;
+	memcpy((void*)&history_list[0],(void*)&history_list[amount],sizeof(HISTORY)*history_count);
+}
+
+void history_set_y_pos(const long y_pos) {
+	history_list[history_index].last_y_pos = y_pos;
 }
 
 long history_get_y_pos(const long idx_article)
@@ -164,6 +181,16 @@ int history_list_save(int level)
 	return rc;
 }
 
+void history_navigate(int articles) {
+	int index = history_index - articles;
+	if (index < 0 || index >= history_count)
+		return;
+	history_index -= articles;
+	long idx_article = history_get_article();
+	
+	display_revisited_article(idx_article);
+}
+
 void draw_clear_history(int bClear)
 {
 	int i;
diff --git a/wiki-app/history.h b/wiki-app/history.h
index 6117783..d10c756 100644
--- a/wiki-app/history.h
+++ b/wiki-app/history.h
@@ -34,15 +34,18 @@
 
 void history_clear(void);
 
-void history_add(const long idx_article, const char *title, int b_keep_pos);
+void history_add(const long idx_article, const char *title, int b_keep_pos, int b_shift);
 unsigned int history_get_count();
 void history_list_init(void);
 int history_list_save(int level);
 
 void history_open_article(int new_selection);
 void history_reload();
-void history_log_y_pos(const long y_pos);
+long history_get_article();
+void history_shift(int amount);
+void history_set_y_pos(const long y_pos);
 long history_get_y_pos(const long idx_article);
+void history_navigate(int articles);
 void draw_clear_history(int bFlag);
 
 typedef struct _HISTORY {
diff --git a/wiki-app/lcd_buf_draw.c b/wiki-app/lcd_buf_draw.c
index 51bceb1..9d80619 100644
--- a/wiki-app/lcd_buf_draw.c
+++ b/wiki-app/lcd_buf_draw.c
@@ -106,6 +106,8 @@ int stop_render_article = 0;
 int b_show_scroll_bar = 0;
 long saved_idx_article;
 
+bool hist_revisit = false;
+
 #define MIN_BAR_LEN 20
 void show_scroll_bar(int bShow)
 {
@@ -1199,7 +1201,7 @@ void display_article_with_pcf(int start_y)
 	if (lcd_draw_cur_y_pos < 0)
 		lcd_draw_cur_y_pos = 0;
 	if (display_mode == DISPLAY_MODE_ARTICLE)
-		history_log_y_pos(lcd_draw_cur_y_pos);
+		history_set_y_pos(lcd_draw_cur_y_pos);
 
 	pos = (lcd_draw_cur_y_pos*LCD_VRAM_WIDTH_PIXELS)/8;
 
@@ -1223,7 +1225,7 @@ float scroll_speed()
 void scroll_article(void)
 {
 	unsigned long time_now, delay_time;
-	long pos;
+	int article_scroll_actual;
 
 	if(finger_move_speed == 0)
 	  return;
@@ -1244,26 +1246,13 @@ void scroll_article(void)
 		time_scroll_article_last = time_now;
 
 		article_scroll_increment = (float)finger_move_speed * ((float)delay_time / (float)seconds_to_ticks(1));
-
-		lcd_draw_cur_y_pos += article_scroll_increment;
 		finger_move_speed = scroll_speed();
-		if(lcd_draw_cur_y_pos < 0)
-		{
-			lcd_draw_cur_y_pos = 0;
-			finger_move_speed = 0;
-		}
-		else if (lcd_draw_cur_y_pos > lcd_draw_buf.current_y - LCD_HEIGHT_LINES)
-		{
-			lcd_draw_cur_y_pos = lcd_draw_buf.current_y - LCD_HEIGHT_LINES;
+		
+		article_scroll_actual = scroll_article_raw(article_scroll_increment);
+		if (article_scroll_actual != article_scroll_increment)
 			finger_move_speed = 0;
-		}
-		if (display_mode == DISPLAY_MODE_ARTICLE)
-			history_log_y_pos(lcd_draw_cur_y_pos);
-
-		pos = (lcd_draw_cur_y_pos*LCD_VRAM_WIDTH_PIXELS)/8;
-
-		repaint_framebuffer(lcd_draw_buf.screen_buf,pos, 1);
-
+		
+		
 		if (finger_move_speed == 0 && b_show_scroll_bar)
 		{
 			b_show_scroll_bar = 0;
@@ -1272,6 +1261,48 @@ void scroll_article(void)
 	}
 }
 
+int scroll_article_raw(int amount)
+{
+	long pos;
+	int lcd_draw_new_y_pos;
+
+	if (!display_first_page || request_display_next_page ||
+		((display_mode == DISPLAY_MODE_INDEX || display_mode == DISPLAY_MODE_HISTORY) &&
+		article_link_count <= NUMBER_OF_FIRST_PAGE_RESULTS))
+	{
+		return 0;
+	}
+	
+	lcd_draw_new_y_pos = lcd_draw_cur_y_pos + amount;
+	if(lcd_draw_new_y_pos < 0)
+	{
+		amount = -lcd_draw_cur_y_pos;
+	}
+	else if (lcd_draw_new_y_pos > lcd_draw_buf.current_y - LCD_HEIGHT_LINES)
+	{
+		amount = lcd_draw_buf.current_y - LCD_HEIGHT_LINES - lcd_draw_cur_y_pos;
+	}	
+	lcd_draw_cur_y_pos += amount;
+	
+	if (display_mode == DISPLAY_MODE_ARTICLE)
+		history_set_y_pos(lcd_draw_cur_y_pos);
+
+	pos = (lcd_draw_cur_y_pos*LCD_VRAM_WIDTH_PIXELS)/8;
+
+	repaint_framebuffer(lcd_draw_buf.screen_buf,pos, 1);
+
+	return amount;
+}
+
+void scroll_article_page(int pages) {
+	int pixels = pages * LCD_HEIGHT_LINES;
+	if (pages > 0)
+		pixels -= lcd_draw_buf.line_height;
+	else
+		pixels += lcd_draw_buf.line_height;
+	scroll_article_raw(pixels);
+}
+
 void display_retrieved_article(long idx_article)
 {
 	int i;
@@ -1280,13 +1311,13 @@ void display_retrieved_article(long idx_article)
 	char title[MAX_TITLE_SEARCH];
 	int link_count_addon = 0;
 	int bKeepPos = 0;
-
+	
 	if (last_display_mode == DISPLAY_MODE_HISTORY)
 	{
 		init_render_article(history_get_y_pos(idx_article));
 		bKeepPos = 1;
 	}
-	else
+	else if (!hist_revisit)
 	{
 		init_render_article(0);
 	}
@@ -1324,7 +1355,11 @@ void display_retrieved_article(long idx_article)
 
 	display_first_page = 0; // use this to disable scrolling until the first page of the linked article is loaded
 	get_article_title_from_idx(idx_article, title);
-	history_add(idx_article, title, bKeepPos);
+	if (!hist_revisit) {
+		// Clicking through removes history entries ahead
+		bool bShift = (last_display_mode == DISPLAY_MODE_ARTICLE);
+		history_add(idx_article, title, bKeepPos, bShift);
+	}
 }
 
 int isArticleLinkSelectedSequentialSearch(int x,int y, int start_i, int end_i)
@@ -1487,9 +1522,25 @@ int load_init_article(long idx_init_article)
 #endif
 
 #ifndef WIKIPCF
-void display_link_article(long idx_article)
+void display_revisited_article(long idx_article)
 {
+	request_y_pos = 0;
+	saved_idx_article = idx_article;
+	file_buffer[0] = '\0';
 
+	if (retrieve_article(idx_article))
+	    return;
+
+	if (restricted_article && check_restriction(idx_article))
+		return;
+
+	hist_revisit = true;
+	init_render_article(history_get_y_pos(idx_article));
+	display_link_article(idx_article);	
+	hist_revisit = false;
+}
+void display_link_article(long idx_article)
+{
 	request_y_pos = 0;
 	if (idx_article == RESTRICTED_MARK_LINK)
 	{
@@ -1968,3 +2019,5 @@ void msg_on_lcd_clear(int x, int y)
 //	guilib_fb_unlock();
 #endif
 }
+
+
diff --git a/wiki-app/lcd_buf_draw.h b/wiki-app/lcd_buf_draw.h
index a533f3a..5cb3d55 100644
--- a/wiki-app/lcd_buf_draw.h
+++ b/wiki-app/lcd_buf_draw.h
@@ -266,12 +266,15 @@ void init_file_buffer();
 int div_wiki(int a,int b);
 int GetFontLinespace(int font);
 #ifndef WIKIPCF
+void display_revisited_article(long idx_article);
 void display_link_article(long idx_article);
 void display_retrieved_article(long idx_article);
 void display_str(char *str);
 void open_article_link(int x,int y);
 void open_article_link_with_link_number(int article_link_number);
 void scroll_article(void);
+int scroll_article_raw(int amount);
+void scroll_article_page(int pages);
 int draw_bmf_char(ucs4_t u,int font,int x,int y, int inverted);
 int buf_draw_bmf_char(char *buf, ucs4_t u,int font,int x,int y, int inverted);
 int isArticleLinkSelected(int x,int y);
diff --git a/wiki-app/wikilib.c b/wiki-app/wikilib.c
index d0f4547..4c0516d 100644
--- a/wiki-app/wikilib.c
+++ b/wiki-app/wikilib.c
@@ -95,6 +95,7 @@ bool article_moved = false;
 #define SMOOTH_SCROLL_ACTIVATION_SPPED_THRESHOLD 50
 #define LIST_SMOOTH_SCROLL_SPEED_FACTOR 5
 #define ARTICLE_SMOOTH_SCROLL_SPEED_FACTOR 3
+#define TAPBORDER 15
 int  article_scroll_pixel = INITIAL_ARTICLE_SCROLL_PIXEL;
 int article_moved_pixels = 0;
 extern int link_to_be_inverted;
@@ -727,7 +728,7 @@ static void handle_touch(struct wl_input_event *ev)
 			article_moved_pixels = 0;
 			touch_y_last_unreleased = 0;
 			start_move_time = 0;
-
+			
 			article_link_number = get_activated_article_link_number();
 			if(article_link_number>=0)
 			{
@@ -751,6 +752,26 @@ static void handle_touch(struct wl_input_event *ev)
 					init_invert_link();
 				}
 				return;
+			} else if (finger_move_speed == 0) {
+				// Top tap
+				if (ev->touch_event.y <= TAPBORDER) {
+					scroll_article_page(-1);
+				} 
+				
+				// Bottom tap
+				else if (LCD_HEIGHT_LINES - ev->touch_event.y <= TAPBORDER) {
+					scroll_article_page(1);
+				}
+				
+				// Left tap
+				else if (ev->touch_event.x <= TAPBORDER) {
+					history_navigate(-1);
+				}
+				
+				// Right tap
+				else if (LCD_WIDTH_PIXELS - ev->touch_event.x <= TAPBORDER) {
+					history_navigate(1);
+				}
 			}
 
 			reset_article_link_number();
-- 
1.6.5.2

_______________________________________________
Openmoko community mailing list
community@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/community

Reply via email to