Clone in a terminal:
Commit de59173
Johan Mattsson - 2012-08-03T18:53:46+00:00
de59173f09aa4e960a64556749cf6f34d6d485bdjohan.mattsson.m@gmail.com

add a scrollbar and some new scrolling code in OverView

Changed files (6)

Diff

diff --git a/src/GlyphRange.vala b/src/GlyphRange.valaindex f1be1bc..90d3e7b 100644--- a/src/GlyphRange.vala+++ b/src/GlyphRange.vala@@ -77,7 +77,8 @@ class GlyphRange { 	} 	 	public void use_full_unicode_range () {-		add_range ('\0', (unichar) 0xA868FE00);+		// add_range ('\0', (unichar) 0xA868FE00);+		add_range ('\0', (unichar) 0xFFF8); 	} 	 	// Todo: complete localized alphabetical sort åäö is the right order for example.diff --git a/src/MainWindow.vala b/src/MainWindow.valaindex aa81dce..edff73e 100644--- a/src/MainWindow.vala+++ b/src/MainWindow.vala@@ -22,7 +22,8 @@ namespace Supplement { 
 public class MainWindow : Gtk.Window {
 
-	HBox hb;
+	HBox list_box;
+	HBox canvas_box;
 	
 	static TabBar tabs;
 	VBox tab_box;
@@ -36,6 +37,8 @@ public class MainWindow : Gtk.Window { 		
 	static DrawingArea margin_bottom;
 	static DrawingArea margin_right;
+
+	static OverView over_view;
 	
 	public MainWindow (string title) {
 		singleton = this;
@@ -64,27 +67,31 @@ public class MainWindow : Gtk.Window { 			FontDisplay fd = tab.get_display ();
 			glyph_canvas.set_current_glyph (fd);
 		});
-		
-		OverView over_view = new OverView();
-		
+
+		over_view = new OverView();
+				
 		tabs.add_unique_tab (content, 60, true);
 		tabs.add_unique_tab (over_view, 75, false);
 		
-		tabs.select_tab_name ("Content");
-				
-		hb = new HBox (false, 0);
+		tabs.select_tab_name ("File");
+		
+		canvas_box = new HBox (false, 0);
+		canvas_box.pack_start (glyph_canvas, true, true, 0);
 		
 		tab_box = new VBox (false, 0);
 		tab_box.pack_start (tabs, false, false, 0);	
-		tab_box.pack_start (glyph_canvas, true, true, 0);
+		
+		tab_box.pack_start (canvas_box, true, true, 0);
+
 		tab_box.pack_start (tool_tip, false, false, 0);
 		tab_box.pack_start (margin_bottom, false, false, 0);
 		
-		hb.pack_start (tab_box, true, true, 0);
-		hb.pack_start (tools, false, false, 0);
-		hb.pack_start (margin_right, false, false, 0);
+		list_box = new HBox (false, 0);
+		list_box.pack_start (tab_box, true, true, 0);
+		list_box.pack_start (tools, false, false, 0);
+		list_box.pack_start (margin_right, false, false, 0);
 
-		add (hb);
+		add (list_box);
 				
 		key_snooper_install (global_key_bindings, null);
 		
diff --git a/src/OverView.vala b/src/OverView.valaindex b95a489..bab7c03 100644--- a/src/OverView.vala+++ b/src/OverView.vala@@ -51,10 +51,16 @@ class OverView : FontDisplay {  	List<GlyphCollection> deleted_glyphs = new List<GlyphCollection> (); +	Scrollbar scrollbar;+	 	public OverView (GlyphRange? range = null) {+		GlyphRange gr;+		 		if (range == null) {-			glyph_range = new GlyphRange ();-			glyph_range.use_default_range ();+			gr = new GlyphRange ();+			gr.use_default_range ();+			+			set_glyph_range (gr); 		} 		 		reset_zoom ();@@ -83,6 +89,50 @@ class OverView : FontDisplay { 				z.store_current_view (); 			} 		});+		+		scrollbar = new Scrollbar ();+		scrollbar.signal_scroll.connect ((delta, delta_last, absolute) => {+			int64 adjustement = (int64) (-delta_last * get_height ());+			int64 pixels = (int64) (-5.0 * delta_last * nail_height);+			+			// print (@"(int64) $(-delta_last) * $(over_view.get_height ()) = $adjustement \n");+			print (@"$delta\n");+	+			if (absolute <= 0.002) {+				first_character = 0;+				first_visible = 0;+				selected = 0;+				scroll_top ();+			} else if (absolute >= 1) {+				scroll_bottom ();+			} else {+				scroll_to (absolute);+			}+			+/*+			if (-0.1 < delta < 0.1) {+				scroll_adjustment (pixels);+			} else {+				scroll_to (absolute);+			}+*/			+			+			redraw_area (0, 0, allocation.width, allocation.height);+		});+		+		update_scrollbar ();+	}+	+	void scroll_bottom () {+		scroll_to_position (glyph_range.length () - items_per_row * (rows - 1));+	}+	+	public double get_height () {+		return 2.0 * nail_height * (glyph_range.length () / rows);+	}++	public bool selected_char_is_visible () {+		return first_visible <= selected <= first_visible + items_per_row * rows; 	}  	public override void scroll_wheel_up (Gdk.EventScroll e) {@@ -258,8 +308,8 @@ class OverView : FontDisplay { 			character_string = glyph_range.get_char ((uint32) index); 			 			if (character_string == "") {-				warning ("Got null character as name for glyph.");-				break;+				warning (@"Got null character as name for glyph. Index: $index");+				// break; 			} 			 			cr.save ();@@ -359,7 +409,8 @@ class OverView : FontDisplay { 		double y; 		uint64 t; 		int i;-+		int n_items;+		 		while (visible_characters.length () > 9) { 			visible_characters.remove_link (visible_characters.first ()); 		}@@ -372,11 +423,12 @@ class OverView : FontDisplay { 		cr.fill (); 		cr.restore (); 		-		int n_items = (allocation.width / nail_width);+		scrollbar.draw (cr, allocation);+		+		n_items = (allocation.width / nail_width); 		rows = (allocation.height / nail_height);-				-		if (items_per_row != n_items) {-				+		+		if (items_per_row != n_items) { 	 			if (items_per_row == 0) { 				items_per_row = n_items; 				first_visible = first_character;@@ -384,20 +436,14 @@ class OverView : FontDisplay { 				items_per_row = n_items; 				first_visible = first_character; 				-				while (selected <= first_visible)+				while (selected < first_visible) { 					scroll (-nail_height);+				} 					-				while (selected <= first_visible + rows * n_items)-					scroll (nail_height);-					+				while (selected < first_visible + rows * n_items) {+					scroll (nail_height);	+				}	 			}-			-			scroll_top ();-			-			while (first_visible < selected) {-				scroll_rows (1);-			}-			scroll_rows (-2); 		}  		width = nail_width * items_per_row;@@ -435,22 +481,80 @@ class OverView : FontDisplay { 		} 	} 	-	public void scroll (int pixel_adjustment) {-		view_offset_y += pixel_adjustment;+	public void scroll_adjustment (double pixel_adjustment) {+		if (first_visible <= 0) {+			return;+		}++		if (first_visible + rows * items_per_row >= glyph_range.length ()) {+			return;+		} 		-		if (view_offset_y >= 0) {			-			view_offset_y = -nail_height;-			first_visible -= items_per_row;+		scroll ((int64) pixel_adjustment);+	}+	+	void default_position () {+		scroll_top ();+		scroll_rows (1);+	}+	+	void scroll_to_position (int64 r) {+		// bottom+		if (r > glyph_range.length () - items_per_row * rows) {+			return; 		} 		-		if (view_offset_y < -nail_height) {-			view_offset_y = 0;-			first_visible += items_per_row;+		if (r < 0) {+			scroll_top ();+			return; 		} 		-		if (first_visible < 0) {+		default_position ();+		+		// DEL:+		// view_offset_y = 0;+		// first_character = (uint32) r;+		first_visible = r;+		selected = (uint32) r;+		+		adjust_scroll ();+	}+	+	public void scroll_to (double percent) {+		int64 r;+		+		print (@"percent $percent\n");+		+		r = (int64) (percent * glyph_range.length () / rows);+		r *= items_per_row;+		+		scroll_to_position (r);+		+		print (@"i: $r $(glyph_range.get_char ((uint32) r)) l: $(glyph_range.length ()) \n");+	}+		+	private void scroll (int64 pixel_adjustment) {++		if (first_visible < 0 && pixel_adjustment < 0) { 			scroll_top ();+			return; 		}+				+		view_offset_y += pixel_adjustment;+		+		if (view_offset_y >= 0) {+			while (view_offset_y > nail_height) {			+				view_offset_y -= nail_height;+				first_visible -= items_per_row;+			}++			first_visible -= items_per_row;+			view_offset_y -= nail_height;+		} else if (view_offset_y < -nail_height) {+			view_offset_y = 0;+			first_visible += items_per_row;+		}+		 	} 	 	public void scroll_top () {@@ -482,7 +586,9 @@ class OverView : FontDisplay { 		} 	} -	private void key_down () {+	public void key_down () {+		update_scrollbar ();+		 		if (glyph_range.length () == 0) return; 	 		if (at_bottom ()) {@@ -513,10 +619,14 @@ class OverView : FontDisplay { 		adjust_scroll (); 	} -	private void key_up () {+	public void key_up () {+		update_scrollbar ();+		 		if (glyph_range.length () == 0) return; 		-		warn_if_fail (selected >= first_character);+		if (selected < first_character) {		+			warn_if_reached ();+		} 		 		if (selected < first_character + items_per_row) { 			scroll_top ();@@ -689,9 +799,15 @@ class OverView : FontDisplay { 	} 		 	public override void motion_notify (EventMotion e) {+		if (e.x > allocation.x - 10) {+			scrollbar.motion_notify (e);+		} 	} 	-	public override void button_release (EventButton event) {+	public override void button_release (EventButton e) {+		if (e.x > allocation.x - 10) {+			scrollbar.button_release (e);+		} 	} 	 	public override void leave_notify (EventCrossing e) {@@ -771,7 +887,11 @@ class OverView : FontDisplay { 	} 	 	public override void button_press (EventButton e) {-		selection_click (e);+		if (e.x > allocation.width - 10) {+			scrollbar.button_press (e);+		} else {+			selection_click (e);+		} 	}  	/** Returns true if overview shows the last character. */@@ -783,7 +903,7 @@ class OverView : FontDisplay { 		string c = glyph_range.get_char (selected); 		bool done = false; 		uint32 i;-		uint32 len;+		uint32 len = 0; 		 		glyph_range = range; 		@@ -849,10 +969,15 @@ class OverView : FontDisplay { 				scroll_top (); 			} 		}-		++		update_scrollbar (); 		redraw_area (0, 0, allocation.width, allocation.height); 	} +	public void update_scrollbar () {+		scrollbar.set_handle_size (items_per_row * rows / (double) glyph_range.get_length ());+		scrollbar.set_handle_position (first_visible / (double) glyph_range.get_length ());+	} }  }diff --git a/src/Scrollbar.vala b/src/Scrollbar.valanew file mode 100644index 0000000..ae2fdf0--- /dev/null+++ b/src/Scrollbar.vala@@ -0,0 +1,181 @@+/*+    Copyright (C) 2012 Johan Mattsson++    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 3 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, see <http://www.gnu.org/licenses/>.+*/++using Cairo;+using Gdk;+using Gtk;++namespace Supplement {++class Scrollbar : DrawingArea {+	Allocation alloc;++	double pos = 0;+	double height = 0.1;+	+	double y = 0;+	double h = 0;+	+	double y_begin = 0;+	double y_last = 0;+	bool move = false;+	bool visible = true;++	public signal void signal_scroll (double delta, double delta_last, double absolute);++	public Scrollbar () {+		add_events (EventMask.BUTTON_PRESS_MASK | EventMask.BUTTON_RELEASE_MASK | EventMask.POINTER_MOTION_MASK);+		+		expose_event.connect ((t, e)=> {+			Context cr = cairo_create (get_window ());+			+			get_allocation (out alloc);+			allocation = alloc;+			+			draw (cr, alloc);+			+			return true;+		});+		+		button_press_event.connect ((t, e)=> {+			button_press (e);			+			return true;+		});++		button_release_event.connect ((t, e)=> {+			button_release (e);+			return true;+		});+		+		motion_notify_event.connect ((t, e)=> {+			motion_notify (e);		+			return true;+		});+	}+	+	public void set_handle_size (double s) {+		height = (s < 0.01) ? 0.01 : s;+		print (@"height $height\n");+		+		if (height > 1) {+			height = 1;+		}+		+		h = height * alloc.height;+	}++	public void set_handle_position (double p) {+		print (@"p: $p\n");+		pos = (p > 0) ? p : 0;+		y = pos * alloc.height;+	}+	+	public void button_press (EventButton e) {+		move = true;+		y_begin = e.y;+		y_last = e.y;+		+		print ("press\n");+	}+	+	public void button_release (EventButton event) {+		move = false;+	}+	+	public double get_height () {+		return alloc.height;+	}+	+	public void motion_notify (EventMotion e) {+		print (@"notify $move \n");+		double d = 0;+		double dl = 0;+		double m;+		+		h = height * alloc.height;+		m = alloc.height;+				+		if (move && 0 < e.y < m) {+			d = e.y - y_begin;+			dl = e.y - y_last;+			y += dl;+			y_last = e.y;+		}++		if (y < 0) {+			y = 0;+		}++		if (y > alloc.height - h) {+			y = alloc.height - h;+			d = 0;+			dl = 0;+		}+		+		if (move) {+			pos = y / alloc.height;+		}+		+		print (@"pos $pos\n");+		+		if (move) {+			signal_scroll (d / (m - h), dl / (m -h), y / (m - h));+			pos = y / m;+		}++	}+		+	public void draw (Context cr, Allocation alloc) {+		double ax, ay, aw, ah;++		this.alloc = alloc;++		ax = alloc.width - 10;+		ay = 0;+		aw = alloc.width;+		ah = alloc.height;+						+		if (!visible) {+			cr.save ();+			cr.rectangle (ax, ay, aw, ah);+			cr.set_line_width (0);+			cr.set_source_rgba (194/255.0, 194/255.0, 194/255.0, 1);+			cr.fill_preserve ();+			cr.stroke ();+			cr.restore ();+			return;+		}+		+		cr.save ();+		cr.rectangle (ax, ay, aw, ah);+		cr.set_line_width (0);+		cr.set_source_rgba (183/255.0, 200/255.0, 223/255.0, 1);+		cr.fill_preserve ();+		cr.stroke ();+		cr.restore ();	+		+		cr.save ();+		cr.rectangle (ax, pos * alloc.height, alloc.width, ah * height);+		cr.set_line_width (0);+		cr.set_source_rgba (133/255.0, 143/255.0, 174/255.0, 1);+		cr.fill_preserve ();+		cr.stroke ();+		cr.restore ();			+	}+}++}diff --git a/src/TestCases.vala b/src/TestCases.valaindex 2c2c546..de4f455 100644--- a/src/TestCases.vala+++ b/src/TestCases.vala@@ -23,6 +23,7 @@ class TestCases { 	public List<Test> test_cases;  	public TestCases () {+		add (test_overview, "Overview"); 		add (test_data_reader, "Font data reader"); 		add (test_argument, "Argument list"); 		add (test_glyph_ranges, "Glyph ranges");@@ -38,6 +39,40 @@ class TestCases { 		add (test_save_backup, "Save backup"); 	} +	public static void test_overview () {+		OverView o = MainWindow.get_overview ();++		warn_if_fail (o.selected_char_is_visible ());+	+		for (int i = 0; i < 10; i++) {+			o.key_down ();+			warn_if_fail (o.selected_char_is_visible ());+		}++		for (int i = 0; i < 15; i++) {+			o.key_up ();+			warn_if_fail (o.selected_char_is_visible ());+		}++		for (int i = 0; i < 6; i++) {+			o.key_down ();+			warn_if_fail (o.selected_char_is_visible ());+		}++		for (int i = 0; i < 3; i++) {+			o.key_down ();+			warn_if_fail (o.selected_char_is_visible ());+		}+		+		for (int i = 0; i < 2000; i++) {+			o.scroll_adjustment (5);+		}++		for (int i = 0; i < 2000; i++) {+			o.scroll_adjustment (-5);+		}+	}+ 	public static void test_data_reader () { 		FontData fd = new FontData (); 		diff --git a/src/wscript b/src/wscriptindex 9b127b2..8426c5c 100644--- a/src/wscript+++ b/src/wscript@@ -36,10 +36,11 @@ SUPPLEMENT_MAIN = [ 	'Path.vala',
 	'PenTool.vala',
 	'ResizeTool.vala',
-	'Supplement.vala',
 	'SaveDialog.vala',
+	'Scrollbar.vala',
 	'ShrinkTool.vala',
 	'SpinButton.vala',
+	'Supplement.vala',
 	'Svg.vala',
 	'SvgFontFormatWriter.vala',
 	'Preferences.vala',

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112