Clone in a terminal:
Commit 8202ce2
Johan Mattsson - 2014-11-14T18:42:51+00:00
8202ce2687220e41598a9ab58d35c7019714a67cjohan.mattsson.m@gmail.com

Customizable key bindings

Changed files (12)

Diff

diff --git a/libbirdfont/Expander.vala b/libbirdfont/Expander.valaindex dc5d3d5..ef27ad3 100644--- a/libbirdfont/Expander.vala+++ b/libbirdfont/Expander.vala@@ -81,7 +81,7 @@ public class Expander : GLib.Object { 		unique = u; 	} 	-	private void update_tool_position () {+	public void update_tool_position () { 		double scale = Toolbox.get_scale (); 		double margin_small = 5 * scale; 		double xt = x;diff --git a/libbirdfont/KeyBindings.vala b/libbirdfont/KeyBindings.valaindex e36cfe0..ab2f484 100644--- a/libbirdfont/KeyBindings.vala+++ b/libbirdfont/KeyBindings.vala@@ -103,7 +103,7 @@ public class KeyBindings { 		require_modifier = t; 	} -	private static uint get_mod_from_key (uint keyval) {+	public static uint get_mod_from_key (uint keyval) { 		uint mod = 0; 		mod |= (keyval == Key.CTRL_RIGHT || keyval == Key.CTRL_LEFT) ? CTRL : 0; 		mod |= (keyval == Key.SHIFT_RIGHT || keyval == Key.SHIFT_LEFT) ? SHIFT : 0;diff --git a/libbirdfont/Menu.vala b/libbirdfont/Menu.valaindex 06c7a2b..54815f6 100644--- a/libbirdfont/Menu.vala+++ b/libbirdfont/Menu.vala@@ -50,6 +50,7 @@ public class Menu : GLib.Object { 	double height = 25 * MainWindow.units; 	 	public Gee.HashMap<string, MenuItem> menu_items = new Gee.HashMap<string, MenuItem> ();+	public Gee.ArrayList<MenuItem> sorted_menu_items = new Gee.ArrayList<MenuItem> ();  	public Menu () { 		SubMenu menu = new SubMenu ();@@ -420,7 +421,6 @@ public class Menu : GLib.Object {  		add_tool_key_bindings (); 		load_key_bindings ();-		write_key_bindings (); 	}  	void load_key_bindings () {@@ -443,12 +443,7 @@ public class Menu : GLib.Object { 		try { 			FileUtils.get_contents((!) f.get_path (), out xml_data); 			parser = new XmlParser (xml_data);-			-			foreach (Tag tag in parser) {-				if (tag.get_name () == "bindings") {-					parse_bindings (tag);-				}-			}+			parse_bindings (parser.get_root_tag ()); 		} catch (GLib.Error e) { 			warning (e.message); 		}@@ -456,8 +451,8 @@ public class Menu : GLib.Object {  	void parse_bindings (Tag tag) { 		foreach (Tag t in tag) {-			if (tag.get_name () == "action") {-				parse_binding (tag.get_attributes ());+			if (t.get_name () == "action") {+				parse_binding (t.get_attributes ()); 			} 		} 	}@@ -496,7 +491,9 @@ public class Menu : GLib.Object { 		} 		 		ma = menu_items.get (action);-		if (ma != null) {+		if (ma == null) {+			warning (@"No action for $action");+		} else { 			menu_action = (!) ma; 			menu_action.modifiers = modifier; 			menu_action.key = key;@@ -508,6 +505,7 @@ public class Menu : GLib.Object { 		 		if (description != "") { 			menu_items.set (description, i);+			sorted_menu_items.add (i); 		} 								 		return i;@@ -540,6 +538,7 @@ public class Menu : GLib.Object { 					tool_item = new ToolItem (t); 					if (tool_item.identifier != "") { 						menu_items.set (tool_item.identifier, tool_item);+						sorted_menu_items.add (tool_item); 					} 				} 			}@@ -635,19 +634,6 @@ public class Menu : GLib.Object { 			items = new Gee.ArrayList<MenuItem> (); 		} 	}-	-	public class ToolItem : MenuItem {-		public ToolItem (Tool tool) {-			base (tool.tip, tool.name);-			-			modifiers = tool.modifier_flag;-			key = tool.key;-			-			action.connect (() => {-				tool.select_action (tool);-			});-		}-	} }  }diff --git a/libbirdfont/MenuItem.vala b/libbirdfont/MenuItem.valaindex e2f68ed..4e8b102 100644--- a/libbirdfont/MenuItem.vala+++ b/libbirdfont/MenuItem.vala@@ -19,6 +19,8 @@ public class MenuItem : GLib.Object { 	public signal void action (); 	public Text label; 	public string identifier;++	public double y; 	 	// key bindings 	public uint modifiers = NONE;@@ -28,8 +30,37 @@ public class MenuItem : GLib.Object { 		this.label = new Text (); 		this.label.set_text (label); 		this.identifier = identifier;+		y = 0;+	}++	public string get_key_bindings () {+		string key_binding = "";+		+		if (key != '\0') {+			key_binding += "(";+			+			if ((modifiers & CTRL) > 0) {+				key_binding += "Ctrl+";+			}+			+			if ((modifiers & ALT) > 0) {+				key_binding += "Alt+";+			}+			+			if ((modifiers & LOGO) > 0) {+				key_binding += "Command+";+			}+			+			if ((modifiers & SHIFT) > 0) {+				key_binding += "Shift+";+			}+			+			key_binding += (!) key.to_string ();+			key_binding += ")";+		}+		+		return key_binding; 	}-	 }  }diff --git a/libbirdfont/Renderer/Text.vala b/libbirdfont/Renderer/Text.valaindex 055de8d..83c0583 100644--- a/libbirdfont/Renderer/Text.vala+++ b/libbirdfont/Renderer/Text.vala@@ -38,7 +38,7 @@ public class Text { 	 	FontCache font_cache; 	Font? current_font;-	string text;+	public string text; 	GlyphSequence glyph_sequence; 	public delegate void Iterator (Glyph glyph, double kerning, bool last); 	diff --git a/libbirdfont/SettingsDisplay.vala b/libbirdfont/SettingsDisplay.valaindex 6a2361c..9775cc1 100644--- a/libbirdfont/SettingsDisplay.vala+++ b/libbirdfont/SettingsDisplay.vala@@ -25,13 +25,18 @@ public class SettingsDisplay : FontDisplay { 	Gee.ArrayList<SettingsItem> tools;  	public static SpinButton precision;-		+	+	SettingsItem new_key_bindings = new SettingsItem.head_line ("");+	bool update_key_bindings = false;+	 	public SettingsDisplay () { 		allocation = new WidgetAllocation (); 		tools = new Gee.ArrayList<SettingsItem> (); 		content_height = 200; 		 		// setting items+		tools.add (new SettingsItem.head_line (t_("Settings")));+		 		ColorTool stroke_color = new ColorTool (); 		stroke_color.color_updated.connect (() => { 			Path.line_color_r = stroke_color.color_r;@@ -210,7 +215,12 @@ public class SettingsDisplay : FontDisplay { 		freehand_samples.new_value_action.connect ((self) => { 			DrawingTools.pen_tool.set_simplification_threshold (simplification_threshold.get_value ()); 		});-+		+		tools.add (new SettingsItem.head_line (t_("Key Bindings")));+		+		foreach (MenuItem menu_item in MainWindow.get_menu ().sorted_menu_items) {+			tools.add (new SettingsItem.key_binding (menu_item));+		} 	}  	public override void draw (WidgetAllocation allocation, Context cr) {@@ -228,40 +238,78 @@ public class SettingsDisplay : FontDisplay { 		cr.fill (); 		cr.stroke (); 		cr.restore ();--		// headline background-		cr.save ();-		cr.set_source_rgba (101 / 255.0, 108 / 255.0, 116 / 255.0, 1);-		cr.rectangle (0, -scroll, allocation.width, 40 * MainWindow.units);-		cr.fill ();-		cr.restore ();-			-		cr.save ();-		headline = new Text ();-		headline.set_text (t_("Settings"));-		cr.set_source_rgba (1, 1, 1, 1);-		headline.draw (cr, 21 * MainWindow.units, 25 * MainWindow.units - scroll, 20 * MainWindow.units);-		cr.restore ();		 		 		foreach (SettingsItem s in tools) {-			s.draw (allocation, cr);+			if (-20 * MainWindow.units <= s.y <= allocation.height + 20 * MainWindow.units) {+				s.draw (allocation, cr);+			} 		} 	}	  	void layout () {-		double y = 50 * MainWindow.units - scroll;+		double y = -scroll;+		bool first = true; 		foreach (SettingsItem s in tools) {+			+			if (!first && s.headline) {+				y += 30 * MainWindow.units;+			}+			 			s.y = y;-			y += 40 * MainWindow.units;+			+			if (s.button != null) {+				((!) s.button).y = y;+				((!) s.button).x = 20 * MainWindow.units;+			}+			+			if (s.headline) {+				y += 50 * MainWindow.units;+			} else {+				y += 40 * MainWindow.units;+			}+			+			first = false; 		}+ 		content_height = y + scroll; 	} -	public override void button_press (uint button, double x, double y) {+	void set_key_bindings (SettingsItem item) {	+		if (new_key_bindings.active) {+			new_key_bindings.active = false;+			update_key_bindings = false;+		} else {	+			new_key_bindings.active = false;+			new_key_bindings = item;+			update_key_bindings = true;+			new_key_bindings.active = true;+		}+	}++	public override void key_release (uint keyval) {+		if (update_key_bindings) {+			if (KeyBindings.get_mod_from_key (keyval) == 0) {+				new_key_bindings.menu_item.modifiers = KeyBindings.modifier;+				new_key_bindings.menu_item.key = (unichar) keyval;+				update_key_bindings = false;+				new_key_bindings.active = false;+				MainWindow.get_menu ().write_key_bindings ();+				GlyphCanvas.redraw ();+			}+		}+	}++	public override void button_press (uint button, double x, double y) {	 		foreach (SettingsItem s in tools) {-			if (s.button.is_over (x, y)) {-				s.button.panel_press_action (s.button, button, x, y);-				s.button.select_action (s.button);+			if (s.handle_events && s.button != null) {+				if (((!) s.button).is_over (x, y)) {+					((!) s.button).panel_press_action ((!) s.button, button, x, y);+					((!) s.button).set_selected (! ((!) s.button).selected);+					+					if (((!) s.button).selected) {+						((!) s.button).select_action ((!) s.button);+					}+				} 			} 		} 		GlyphCanvas.redraw ();@@ -269,8 +317,14 @@ public class SettingsDisplay : FontDisplay { 	 	public override void button_release (int button, double x, double y) { 		foreach (SettingsItem s in tools) {-			if (s.button.is_over (x, y) || s.button.is_active ()) {-				s.button.panel_release_action (s.button, button, x, y);+			if (s.handle_events && s.button != null) {+				if (((!) s.button).is_over (x, y) || ((!) s.button).is_active ()) {+					((!) s.button).panel_release_action ((!) s.button, button, x, y);+				}+			}+			+			if (s.key_bindings && s.y <= y < s.y + 40 * MainWindow.units && button == 1) {+				set_key_bindings (s); 			} 		} 		GlyphCanvas.redraw ();@@ -280,8 +334,10 @@ public class SettingsDisplay : FontDisplay { 		bool consumed = false; 		 		foreach (SettingsItem s in tools) {-			if (s.button.panel_move_action (s.button, x, y)) {-				consumed = true;+			if (s.handle_events && s.button != null) {+				if (((!) s.button).panel_move_action ((!) s.button, x, y)) {+					consumed = true;+				} 			} 		} 		@@ -305,13 +361,15 @@ public class SettingsDisplay : FontDisplay { 	 	public override void scroll_wheel_down (double x, double y) { 		foreach (SettingsItem s in tools) {-			if (s.button.is_over (x, y)) {-				s.button.scroll_wheel_down_action (s.button);-				return;+			if (s.handle_events && s.button != null) {+				if (((!) s.button).is_over (x, y)) {+					((!) s.button).scroll_wheel_down_action ((!) s.button);+					return;+				} 			} 		} 		-		scroll += 15 * MainWindow.units;+		scroll += 25 * MainWindow.units;  		if (scroll + allocation.height >=  content_height) { 			scroll = content_height - allocation.height;@@ -323,13 +381,15 @@ public class SettingsDisplay : FontDisplay { 	 	public override void scroll_wheel_up (double x, double y) { 		foreach (SettingsItem s in tools) {-			if (s.button.is_over (x, y)) {-				s.button.scroll_wheel_up_action (s.button);-				return;+			if (s.handle_events && s.button != null) {+				if (((!) s.button).is_over (x, y)) {+					((!) s.button).scroll_wheel_up_action ((!) s.button);+					return;+				} 			} 		} 		-		scroll -= 15 * MainWindow.units;;+		scroll -= 25 * MainWindow.units; 		 		if (scroll < 0) { 			scroll = 0;@@ -340,6 +400,7 @@ public class SettingsDisplay : FontDisplay { 	}  	public override void selected_canvas () {+		MainWindow.get_toolbox ().set_default_tool_size (); 		update_scrollbar (); 		GlyphCanvas.redraw (); 	}@@ -355,32 +416,6 @@ public class SettingsDisplay : FontDisplay { 		scroll = percent * h; 		GlyphCanvas.redraw (); 	}-	-	class SettingsItem : GLib.Object {-		-		public double y;-		public Tool button;-		-		Text label;-		-		public SettingsItem (Tool tool, string description) {-			button = tool;-			label = new Text ();-			label.set_text (description);-			y = 0;-		}-		-		public void draw (WidgetAllocation allocation, Context cr) {-			button.y = y;-			button.x = 20 * MainWindow.units;-			button.draw (cr);-			-			cr.save ();-			cr.set_source_rgba (101 / 255.0, 108 / 255.0, 116 / 255.0, 1);-			label.draw (cr, 60 * MainWindow.units, y + 20 * MainWindow.units, 17 * MainWindow.units);-			cr.restore ();-		}-	} }  }diff --git a/libbirdfont/SettingsItem.vala b/libbirdfont/SettingsItem.valanew file mode 100644index 0000000..f273cbd--- /dev/null+++ b/libbirdfont/SettingsItem.vala@@ -0,0 +1,107 @@+/*+    Copyright (C) 2014 Johan Mattsson++    This library is free software; you can redistribute it and/or modify +    it under the terms of the GNU Lesser General Public License as +    published by the Free Software Foundation; either version 3 of the +    License, or (at your option) any later version.++    This library 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 +    Lesser General Public License for more details.+*/++using Cairo;+using Math;++namespace BirdFont {++class SettingsItem : GLib.Object {	+	public bool handle_events;+	public bool key_bindings = false;+	public double y = 0;+	public Tool? button = null;+	public bool headline = false;+	public MenuItem menu_item = new MenuItem ("");+	public bool active = false;+	+	Text label;+	+	public SettingsItem (Tool tool, string description) {+		button = tool;+		label = new Text ();+		label.set_text (description);+		handle_events = true;+	}+	+	public SettingsItem.key_binding (MenuItem item) {+		if (item is ToolItem) {+			button = ((ToolItem) item).tool;+		}+		+		label = item.label;+		handle_events = false;+		key_bindings = true;+		menu_item = item;+	}+	+	public SettingsItem.head_line (string label) {+		this.label = new Text ();+		this.label.set_text (label);+		+		handle_events = false;+		headline = true;+	}+	+	public void draw (WidgetAllocation allocation, Context cr) {+		Tool t;+		double label_x;+		+		if (headline) {+			cr.save ();+			cr.set_source_rgba (101 / 255.0, 108 / 255.0, 116 / 255.0, 1);+			cr.rectangle (0, y, allocation.width, 40 * MainWindow.units);+			cr.fill ();+			cr.restore ();+				+			cr.save ();+			cr.set_source_rgba (1, 1, 1, 1);+			label.draw (cr, 21 * MainWindow.units, y + 25 * MainWindow.units, 20 * MainWindow.units);+			cr.restore ();+		} else {+			if (active) {+				cr.save ();+				cr.set_source_rgba (38 / 255.0, 39 / 255.0, 43 / 255.0, 1);+				cr.rectangle (0, y - 5 * MainWindow.units, allocation.width, 40 * MainWindow.units);+				cr.fill ();+				cr.restore ();+			}+			+			label_x = button != null ? 70 : 20;+			label_x *= MainWindow.units;+			+			if (button != null) {+				t = (!) button;+				t.draw (cr);+			}+			+			cr.save ();+			cr.set_source_rgba (101 / 255.0, 108 / 255.0, 116 / 255.0, 1);+			label.draw (cr, label_x, y + 20 * MainWindow.units, 17 * MainWindow.units);+			cr.restore ();+			+			if (key_bindings) {+				Text key_binding_text = new Text ();+				key_binding_text.set_text (menu_item.get_key_bindings ());+				cr.save ();+				cr.set_source_rgba (101 / 255.0, 108 / 255.0, 116 / 255.0, 1);+				label_x += label.get_extent (17 * MainWindow.units) + 20 * MainWindow.units;+				key_binding_text.draw (cr, label_x, y + 20 * MainWindow.units, 17 * MainWindow.units);+				cr.restore ();+			}	+		}+	}+}++}diff --git a/libbirdfont/TabContent.vala b/libbirdfont/TabContent.valaindex 93dc434..70b885c 100644--- a/libbirdfont/TabContent.vala+++ b/libbirdfont/TabContent.vala@@ -97,10 +97,8 @@ public class TabContent : GLib.Object { 			return; 		} 		-		if (GlyphCanvas.current_display is Glyph) {-			GlyphCanvas.current_display.key_release (keyval);-		}-		+		GlyphCanvas.current_display.key_release (keyval);+ 		KeyBindings.remove_modifier_from_keyval (keyval); 	} 	diff --git a/libbirdfont/Tool.vala b/libbirdfont/Tool.valaindex 4fb1529..dac8516 100644--- a/libbirdfont/Tool.vala+++ b/libbirdfont/Tool.vala@@ -23,8 +23,8 @@ public class Tool : GLib.Object { 	public double w = 33 * Toolbox.get_scale (); 	public double h = (33 / 1.11) * Toolbox.get_scale (); 	-	protected bool active = false;-	protected bool selected = false;+	public bool active = false;+	public bool selected = false; 	 	ImageSurface? icon = null; 		@@ -250,6 +250,12 @@ public class Tool : GLib.Object { 		cr.save (); 		 		scale = w / 111.0; // scale to 320 dpi+		+		if (unlikely (scale == 0)) {+			warning ("Scale is zero.");+			scale = 33 / 111.0;+		}+		 		cr.scale (scale, scale); 		 		bgx = xt / scale;diff --git a/libbirdfont/ToolItem.vala b/libbirdfont/ToolItem.valanew file mode 100644index 0000000..63dc822--- /dev/null+++ b/libbirdfont/ToolItem.vala@@ -0,0 +1,35 @@+/*+    Copyright (C) 2014 Johan Mattsson++    This library is free software; you can redistribute it and/or modify +    it under the terms of the GNU Lesser General Public License as +    published by the Free Software Foundation; either version 3 of the +    License, or (at your option) any later version.++    This library 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 +    Lesser General Public License for more details.+*/++namespace BirdFont {++public class ToolItem : MenuItem {++	public Tool tool;++	public ToolItem (Tool tool) {+		base (tool.tip, tool.tip); // FIXME: untranslated tip.+		+		this.tool = tool;+		+		modifiers = tool.modifier_flag;+		key = tool.key;+		+		action.connect (() => {+			tool.select_action (tool);+		});+	}+}++}diff --git a/libbirdfont/Toolbox.vala b/libbirdfont/Toolbox.valaindex 80eaa33..725d0a6 100644--- a/libbirdfont/Toolbox.vala+++ b/libbirdfont/Toolbox.vala@@ -393,6 +393,14 @@ public class Toolbox : GLib.Object  { 		return Toolbox.allocation_width / 160.0; 	} 	+	public void set_default_tool_size () {+		foreach (ToolCollection t in tool_sets) {+			foreach (Expander e in t.get_expanders ()) {+				e.update_tool_position ();+			}+		}+	}+	 	public void update_expanders () { 		double pos; 		diff --git a/libbirdxml/Xml.vala b/libbirdxml/Xml.valaindex bab31e2..497ca9e 100644--- a/libbirdxml/Xml.vala+++ b/libbirdxml/Xml.vala@@ -148,10 +148,6 @@ public class XmlParser { 		return root; 	} 	-	public Tag.Iterator iterator () {-		return get_root_tag ().iterator ();-	}-	 	/**  	 * Reset the parser and start from the beginning of the XML document.  	 */

Contact

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