Clone in a terminal:
Commit 6b8a573
Johan Mattsson - 2013-08-14T05:19:08+00:00
6b8a573503dbeb93f30b4850d63f267ff52bded7johan.mattsson.m@gmail.com

split tool box in tools for drawing and tools for drawing

Changed files (11)

Diff

diff --git a/birdfont/GtkWindow.vala b/birdfont/GtkWindow.valaindex 475fecf..4eab87a 100644--- a/birdfont/GtkWindow.vala+++ b/birdfont/GtkWindow.vala@@ -679,13 +679,13 @@ public class GtkWindow : Gtk.Window, NativeWindow { 		Gtk.MenuItem add_grid_item = new Gtk.MenuItem.with_mnemonic (_("Add New _Grid Item")); 		tool_menu.append (add_grid_item); 		add_grid_item.activate.connect (() => { -			MainWindow.get_toolbox ().add_new_grid ();+			MainWindow.get_drawing_tools ().add_new_grid (); 		});  		Gtk.MenuItem remove_grid_item = new Gtk.MenuItem.with_mnemonic (_("Remove Gr_id Item")); 		tool_menu.append (remove_grid_item); 		remove_grid_item.activate.connect (() => { -			MainWindow.get_toolbox ().remove_current_grid ();+			MainWindow.get_drawing_tools().remove_current_grid (); 		}); 		 		Gtk.MenuItem zoom_in_item = new Gtk.MenuItem.with_mnemonic (_("_Zoom In"));diff --git a/libbirdfont/CircleTool.vala b/libbirdfont/CircleTool.valaindex d6592c1..283dbef 100644--- a/libbirdfont/CircleTool.vala+++ b/libbirdfont/CircleTool.vala@@ -107,7 +107,7 @@ public class CircleTool : Tool { 		 		glyph.store_undo_state (); 		-		steps = (Toolbox.point_type == PointType.QUADRATIC) ? PI / 8 : PI / 4;  +		steps = (DrawingTools.point_type == PointType.QUADRATIC) ? PI / 8 : PI / 4;   		 		for (double angle = 0; angle < 2 * PI; angle += steps) { 			px = radius * cos (angle) + Glyph.path_coordinate_x (x);diff --git a/libbirdfont/DrawingTools.vala b/libbirdfont/DrawingTools.valanew file mode 100644index 0000000..9952292--- /dev/null+++ b/libbirdfont/DrawingTools.vala@@ -0,0 +1,771 @@+/*+    Copyright (C) 2012, 2013 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 {++public class DrawingTools : ToolCollection  {+	GlyphCanvas glyph_canvas;+	+	public List<Expander> expanders;+	+	Expander draw_tools;+	Expander grid_expander;+	Expander shape_tools;+	+	BackgroundTool move_background;+	CutBackgroundTool cut_background;+	+	public SpinButton background_scale = new SpinButton ();+	public static SpinButton precision;+	+	public int allocation_width = 0;+	public int allocation_height = 0;+	+	ImageSurface? toolbox_background = null;+	+	public static PointType point_type = PointType.DOUBLE_CURVE;+	+	public DrawingTools (GlyphCanvas main_glyph_canvas) {+		glyph_canvas = main_glyph_canvas;++		toolbox_background = Icons.get_icon ("toolbox_background.png");+		+		draw_tools = new Expander ();+		shape_tools = new Expander ();+			+		Expander path_tool_modifiers = new Expander ();+		Expander draw_tool_modifiers = new Expander ();+		Expander edit_point_modifiers = new Expander ();+		Expander characterset_tools = new Expander ();+		Expander test_tools = new Expander ();+		Expander guideline_tools = new Expander ();+		Expander view_tools = new Expander ();+		Expander grid = new Expander ();+		+		Expander background_tools = new Expander ();+		Expander style_tools = new Expander ();+		+		grid_expander = grid;++		// Draw tools+		PenTool pen_tool = new PenTool ("pen_tool");+		draw_tools.add_tool (pen_tool);+	+		ZoomTool zoom_tool = new ZoomTool ("zoom_tool");+		draw_tools.add_tool (zoom_tool);++		Tool move_tool = new MoveTool ("move");+		draw_tools.add_tool (move_tool);++		// quadratic Bézier points+		Tool quadratic_points = new Tool ("quadratic_points", _("Create quadratic Bézier curves"));+		quadratic_points.select_action.connect ((self) => {+			point_type = PointType.QUADRATIC;+			Preferences.set ("point_type", "quadratic_points");+		});+		draw_tool_modifiers.add_tool (quadratic_points);		++		// cubic Bézier points+		Tool cubic_points = new Tool ("cubic_points", _("Create cubic Bézier curves"));+		cubic_points.select_action.connect ((self) => {+			point_type = PointType.CUBIC;+			Preferences.set ("point_type", "cubic_points");+		});+		draw_tool_modifiers.add_tool (cubic_points);++		// two quadratic points off curve points for each quadratic control point+		Tool double_points = new Tool ("double_points", _("Quadratic path with two line handles"));+		double_points.select_action.connect ((self) => {+			point_type = PointType.DOUBLE_CURVE;+			Preferences.set ("point_type", "double_points");+		});+		draw_tool_modifiers.add_tool (double_points);++		// convert point+		Tool convert_points = new Tool ("convert_point", _("Convert selected points"));+		convert_points.select_action.connect ((self) => {+			PenTool.convert_point_types ();+			MainWindow.get_current_glyph ().update_view ();+		});+		convert_points.set_persistent (false);+		draw_tool_modifiers.add_tool (convert_points);++		// tie edit point handles+		Tool tie_handles = new Tool ("tie_point", _("Tie curve handles for the selected edit point"), 'w');+		tie_handles.select_action.connect ((self) => {+			bool tie;+			+			foreach (EditPoint ep in PenTool.selected_points) {+				tie = !ep.tie_handles;+				+				if (tie) {+					ep.process_tied_handle ();+					ep.set_reflective_handles (false);+				}+			+				ep.set_tie_handle (tie);+			}+			+			MainWindow.get_current_glyph ().update_view ();+		});+		edit_point_modifiers.add_tool (tie_handles);+		+		// symmetrical handles+		Tool reflect_handle = new Tool ("symmetric", _("Symmetrical handles"), 'r');+		reflect_handle.select_action.connect ((self) => {+			bool symmetrical;+			EditPoint ep;+			if (PenTool.selected_points.length () > 0) {+				ep = PenTool.selected_points.first ().data;+				symmetrical = ep.reflective_handles;+				foreach (EditPoint p in PenTool.selected_points) {+					p.set_reflective_handles (!symmetrical);+					p.process_symmetrical_handles ();+					+					if (symmetrical) {+						ep.set_tie_handle (false);+					}+				}+				+				MainWindow.get_current_glyph ().update_view ();+			}+		});+		edit_point_modifiers.add_tool (reflect_handle);++		Tool create_line = new Tool ("create_line", _("Convert segment to line."), 'r');+		create_line.select_action.connect ((self) => {+			PenTool.convert_segment_to_line ();+			MainWindow.get_current_glyph ().update_view ();+		});+		edit_point_modifiers.add_tool (create_line);+	+		// path tools+		Tool union_paths_tool = new Tool ("union_paths", _("Merge paths"));+		union_paths_tool.select_action.connect ((self) => {+			Glyph g = MainWindow.get_current_glyph ();+			g.merge_all ();+		});+		path_tool_modifiers.add_tool (union_paths_tool);+		+		Tool reverse_path_tool = new Tool ("reverse_path", _("Create counter from outline"));+		reverse_path_tool.select_action.connect ((self) => {+			Glyph g = MainWindow.get_current_glyph ();+			+			foreach (Path p in g.active_paths) {+				p.reverse ();+			}+		+			g.redraw_area (0, 0, g.allocation.width, g.allocation.height);+		});+		path_tool_modifiers.add_tool (reverse_path_tool);++		Tool move_layer = new Tool ("move_layer", _("Move to path to the bottom layer"), 'd');+		move_layer.select_action.connect ((self) => {+			Glyph g = MainWindow.get_current_glyph ();++			foreach (Path p in g.active_paths) {+				g.path_list.remove (p);+				g.path_list.prepend (p);+			}+		});+		path_tool_modifiers.add_tool (move_layer);++		Tool flip_vertical = new Tool ("flip_vertical", _("Flip path vertically"));+		flip_vertical.select_action.connect ((self) => {+			MoveTool.flip_vertical ();+			MainWindow.get_current_glyph ().update_view ();+		});+		path_tool_modifiers.add_tool (flip_vertical);++		Tool flip_horizontal = new Tool ("flip_horizontal", _("Flip path horizontally"));+		flip_horizontal.select_action.connect ((self) => {+			MoveTool.flip_horizontal ();+			MainWindow.get_current_glyph ().update_view ();+		});+		path_tool_modifiers.add_tool (flip_horizontal);+		+		// adjust precision+		string precision_value = Preferences.get ("precision");+		+		precision = new SpinButton ("precision", _("Set precision"));+		+		if (precision_value != "") {+			precision.set_value (precision_value);+		} else {+			precision.set_value_round (1);+		}+		+		precision.new_value_action.connect ((self) => {+			MainWindow.get_toolbox ().select_tool (precision);+			+			Preferences.set ("precision", self.get_display_value ());+			MainWindow.get_toolbox ().redraw ((int) precision.x, (int) precision.y, 70, 70);+		});++		precision.select_action.connect((self) => {+			pen_tool.set_precision (((SpinButton)self).get_value ());+		});+		+		precision.set_min (0.001);+		precision.set_max (1);+		+		path_tool_modifiers.add_tool (precision);+		+		// Character set tools+		Tool full_unicode = new Tool ("utf_8", _("Show full unicode characters set"), 'f', CTRL);+		full_unicode.select_action.connect ((self) => {+				MainWindow.get_tab_bar ().add_unique_tab (new OverView (), 100, false);	+				OverView o = MainWindow.get_overview ();+				GlyphRange gr = new GlyphRange ();+				+				if (!BirdFont.get_current_font ().initialised) {+					MenuTab.new_file ();+				}+				+				DefaultCharacterSet.use_full_unicode_range (gr);+				o.set_glyph_range (gr);+				MainWindow.get_tab_bar ().select_tab_name ("Overview");+			});+		characterset_tools.add_tool (full_unicode);++		Tool custom_character_set = new Tool ("custom_character_set", _("Show default characters set"), 'r', CTRL);+		custom_character_set.select_action.connect ((self) => {+			MainWindow.get_tab_bar ().add_unique_tab (new OverView (), 100, false);+			OverView o = MainWindow.get_overview ();+			GlyphRange gr = new GlyphRange ();++			if (!BirdFont.get_current_font ().initialised) {+				MenuTab.new_file ();+			}+			+			DefaultCharacterSet.use_default_range (gr);+			o.set_glyph_range (gr);+			MainWindow.get_tab_bar ().select_tab_name ("Overview");+		});+		characterset_tools.add_tool (custom_character_set);++		Tool avalilable_characters = new Tool ("available_characters", _("Show all characters in the font"), 'd', CTRL);+		avalilable_characters.select_action.connect ((self) => {+			MainWindow.get_tab_bar ().add_unique_tab (new OverView (), 100, false);+			OverView o = MainWindow.get_overview ();+			+			if (!BirdFont.get_current_font ().initialised) {+				MenuTab.new_file ();+			}+			+			o.display_all_available_glyphs ();+			MainWindow.get_tab_bar ().select_tab_name ("Overview");+		});+		characterset_tools.add_tool (avalilable_characters);++		Tool delete_glyph = new Tool ("delete_selected_glyph", _("Delete selected glyph"));+		delete_glyph.select_action.connect ((self) => {+			OverView o = MainWindow.get_overview ();+			+			if (MainWindow.get_current_display () is OverView) {+				o.delete_selected_glyph ();+			}+			+			MainWindow.get_tab_bar ().select_tab_name ("Overview");+		});+		characterset_tools.add_tool (delete_glyph);++		if (BirdFont.has_argument ("--test")) {+			Tool test_case = new Tool ("test_case");+			test_case.select_action.connect((self) => {+					if (self.is_selected ()) {+						if (TestBirdFont.is_running ()) {+							TestBirdFont.pause ();+						} else {+							TestBirdFont.continue ();+						}+					}+				});+			test_tools.add_tool (test_case);++			Tool slow_test = new Tool ("slow_test");+			slow_test.select_action.connect((self) => {+					bool s = TestBirdFont.is_slow_test ();+					TestBirdFont.set_slow_test (!s);+					s = TestBirdFont.is_slow_test ();+					self.set_selected (s);+				});+		+			test_tools.add_tool (slow_test);+					+			// Run from commad line+			string? st = BirdFont.get_argument ("--test");+			if (st != null && ((!)st).char_count () > 0) {+				IdleSource idle = new IdleSource ();++				idle.set_callback (() => {			+					MainWindow.get_toolbox ().select_tool (test_case);+					return false;+				});+				+				idle.attach (null);+			}+			+			if (BirdFont.has_argument ("--slow")) {+				MainWindow.get_toolbox ().select_tool (slow_test);+			}+			+		}+		+		// guide lines, grid and other guidlines+		Tool help_lines = new Tool ("help_lines", _("Show guidelines"), 'l');+		help_lines.select_action.connect ((self) => {+				bool h;+				h = GlyphCanvas.get_current_glyph ().get_show_help_lines ();+				GlyphCanvas.get_current_glyph ().set_show_help_lines (!h);+				self.set_selected (!h);+				GlyphCanvas.get_current_glyph ().redraw_help_lines ();+			});	++		guideline_tools.add_tool (help_lines);++		Tool xheight_help_lines = new Tool ("show_xheight_helplines", _("Show guidelines for x-height and baseline"), 'x');+		xheight_help_lines.select_action.connect ((self) => {+			Glyph g = MainWindow.get_current_glyph ();+			bool v = !g.get_xheight_lines_visible ();+			g.set_xheight_lines_visible (v);+			self.set_selected (v);+			MainWindow.get_glyph_canvas ().redraw ();+			+			if (v && !help_lines.is_selected ()) {+				MainWindow.get_toolbox ().select_tool (help_lines);+			}+			+		});+		guideline_tools.add_tool (xheight_help_lines);++		Tool background_help_lines = new Tool ("background_help_lines", _("Show guidelines at top and bottom margin"), 't');+		background_help_lines.select_action.connect ((self) => {+			Glyph g = MainWindow.get_current_glyph ();+			bool v = !g.get_margin_lines_visible ();+			g.set_margin_lines_visible (v);+			self.set_selected (v);+			MainWindow.get_glyph_canvas ().redraw ();+			+			if (v && !help_lines.is_selected ()) {+				MainWindow.get_toolbox ().select_tool (help_lines);+			}+		});+		guideline_tools.add_tool (background_help_lines);++		Tool new_grid = new GridTool ("new_grid");+		guideline_tools.add_tool (new_grid);++		// Zoom tools +		Tool zoom_in = new Tool ("zoom_in", _("Zoom in"), '+', CTRL);+		zoom_in.select_action.connect ((self) => {+			zoom_tool.store_current_view ();+			glyph_canvas.get_current_display ().zoom_in ();+		});+		view_tools.add_tool (zoom_in);++		Tool zoom_out = new Tool ("zoom_out", _("Zoom out"), '-', CTRL);+		zoom_out.select_action.connect ((self) => {+			zoom_tool.store_current_view ();+			glyph_canvas.get_current_display ().zoom_out ();+		});+		view_tools.add_tool (zoom_out);++		Tool reset_zoom = new Tool ("zoom_1_1", _("Zoom to scale 1:1"), '0', CTRL);+		reset_zoom.select_action.connect ((self) => {+				zoom_tool.store_current_view ();+				glyph_canvas.get_current_display ().reset_zoom ();+				glyph_canvas.redraw_area(0, 0, glyph_canvas.allocation.width, glyph_canvas.allocation.height);+			});+		view_tools.add_tool (reset_zoom);++		Tool full_glyph = new Tool ("full_glyph", _("Show full glyph"));+		full_glyph.select_action.connect((self) => {+			zoom_tool.store_current_view ();+			zoom_tool.zoom_full_glyph ();+		});+		view_tools.add_tool (full_glyph);++		Tool zoom_boundries = new Tool ("zoom_boundries", _("Zoom in at region boundries"), 'v');+		zoom_boundries.select_action.connect((self) => {+			zoom_tool.store_current_view ();+			glyph_canvas.get_current_display ().zoom_max ();+		});+		view_tools.add_tool (zoom_boundries);++		Tool zoom_bg = new Tool ("zoom_background_image", _("Zoom in background image"));+		zoom_bg.select_action.connect((self) => {+			if (MainWindow.get_current_glyph ().get_background_image () != null) {+				zoom_tool.store_current_view ();					+				glyph_canvas.get_current_display ().reset_zoom ();+				+				zoom_tool.zoom_full_background_image ();+				+				glyph_canvas.redraw_area(0, 0, glyph_canvas.allocation.width, glyph_canvas.allocation.height);+			}+		});+		view_tools.add_tool (zoom_bg);++		Tool zoom_prev = new Tool ("prev", _("Previous view"), 'j', CTRL);+		zoom_prev.select_action.connect((self) => {+			zoom_tool.previous_view ();+		});+		view_tools.add_tool (zoom_prev);++		Tool zoom_next = new Tool ("next", _("Next view"), 'l', CTRL);+		zoom_next.select_action.connect((self) => {+			zoom_tool.next_view ();+		});+		view_tools.add_tool (zoom_next);+		+		// shape tools +		Tool circle = new CircleTool ("circle");+		shape_tools.add_tool (circle);+		+		Tool rectangle = new RectangleTool ("rectangle");+		shape_tools.add_tool (rectangle);+				+		// background tools+		background_scale = new SpinButton ("scale_background", _("Set size for background image"));+		background_scale.set_int_value ("1.000");+		+		background_scale.new_value_action.connect((self) => {+			background_scale.select_action (self);+		});+		+		background_scale.select_action.connect((self) => {+			SpinButton sb = (SpinButton) self;+			Glyph g = MainWindow.get_current_glyph ();+			GlyphBackgroundImage? img = g.get_background_image ();+			double s = sb.get_value ();+			+			if (img != null) {+				((!)img).set_img_scale (s, s);+			}+			+			MainWindow.get_glyph_canvas ().redraw ();+		});+		+		background_tools.add_tool (background_scale);		++		BackgroundTool move_background = new BackgroundTool ("move_background");			+		background_tools.add_tool (move_background);+		this.move_background = move_background;+		+		CutBackgroundTool cut_background = new CutBackgroundTool ("cut_background");+		background_tools.add_tool (cut_background);+		this.cut_background = cut_background;+		+		Tool show_bg = new Tool ("show_background", _("Show/hide background image"));+		show_bg.select_action.connect ((self) => {+			Glyph g = MainWindow.get_current_glyph ();+			g.set_background_visible (!g.get_background_visible ());+			MainWindow.get_glyph_canvas ().redraw ();+		});+		background_tools.add_tool (show_bg);++		Tool bg_selection = new Tool ("insert_background", _("Insert a new background image"));+		bg_selection.select_action.connect((self) => {+			Glyph? g = null;+			FontDisplay fd = MainWindow.get_current_display ();+			TooltipArea tp = MainWindow.get_tool_tip ();+			tp.show_text (_("Creating thumbnails"));+			+			Tool.yield ();+		+			if (fd is Glyph) {+				g = (Glyph) fd;+			} else {+				return;+			}+			+			BackgroundSelection bgs = new BackgroundSelection ();+			MainWindow.get_tab_bar ().add_unique_tab (bgs , 120, false);+			+			tp.show_text ("");+		});+		+		bg_selection.set_show_background (true);+		background_tools.add_tool (bg_selection);+		+		SpinButton background_contrast = new SpinButton ("background_contrast", _("Set contrast for background image"));+		background_contrast.set_value_round (1);++		background_contrast.new_value_action.connect ((self) => {+			background_contrast.select_action (self);+		});+		+		background_contrast.select_action.connect ((self) => {		+			Glyph g = MainWindow.get_current_glyph ();+			GlyphBackgroundImage? bg = g.get_background_image ();+			GlyphBackgroundImage b;+			+			if (bg != null) {+				b = (!) bg;+				b.set_contrast (background_contrast.get_value ());+			}+		});++		// color and style+		ColorTool stroke_color = new ColorTool (_("Stroke color"));+		stroke_color.color_updated.connect (() => {+			Path.line_color_r = stroke_color.color_r;+			Path.line_color_g = stroke_color.color_g;+			Path.line_color_b = stroke_color.color_b;+			Path.line_color_a = stroke_color.color_a;++			Preferences.set ("line_color_r", @"$(Path.line_color_r)");+			Preferences.set ("line_color_g", @"$(Path.line_color_g)");+			Preferences.set ("line_color_b", @"$(Path.line_color_b)");+			Preferences.set ("line_color_a", @"$(Path.line_color_a)");++			Glyph g = MainWindow.get_current_glyph ();+			g.redraw_area (0, 0, g.allocation.width, g.allocation.height);+		});+		stroke_color.set_r (double.parse (Preferences.get ("line_color_r")));+		stroke_color.set_g (double.parse (Preferences.get ("line_color_g")));+		stroke_color.set_b (double.parse (Preferences.get ("line_color_b")));+		stroke_color.set_a (double.parse (Preferences.get ("line_color_a")));+		style_tools.add_tool (stroke_color);+		+		SpinButton stroke_width;+		stroke_width = new SpinButton ("stroke_width", _("Stroke width"));+		+		if (Preferences.get ("stroke_width") == "") {+			stroke_width.set_value_round (1);+		} else {+			stroke_width.set_value (Preferences.get ("stroke_width"));+		}+		+		stroke_width.new_value_action.connect((self) => {+			Glyph g = MainWindow.get_current_glyph ();+			Path.stroke_width = stroke_width.get_value ();+			g.redraw_area (0, 0, g.allocation.width, g.allocation.height);+			Preferences.set ("stroke_width", @"$(Path.stroke_width)");+			MainWindow.get_toolbox ().redraw ((int) stroke_width.x, (int) stroke_width.y, 70, 70);+		});+		style_tools.add_tool (stroke_width);++		ColorTool handle_color = new ColorTool (_("Handle color"));+		handle_color.color_updated.connect (() => {+			Path.handle_color_r = handle_color.color_r;+			Path.handle_color_g = handle_color.color_g;+			Path.handle_color_b = handle_color.color_b;+			Path.handle_color_a = handle_color.color_a;++			Preferences.set ("handle_color_r", @"$(Path.handle_color_r)");+			Preferences.set ("handle_color_g", @"$(Path.handle_color_g)");+			Preferences.set ("handle_color_b", @"$(Path.handle_color_b)");+			Preferences.set ("handle_color_a", @"$(Path.handle_color_a)");++			Glyph g = MainWindow.get_current_glyph ();+			g.redraw_area (0, 0, g.allocation.width, g.allocation.height);+		});+		handle_color.set_r (double.parse (Preferences.get ("handle_color_r")));+		handle_color.set_g (double.parse (Preferences.get ("handle_color_g")));+		handle_color.set_b (double.parse (Preferences.get ("handle_color_b")));+		handle_color.set_a (double.parse (Preferences.get ("handle_color_a")));+		style_tools.add_tool (handle_color);+		+		draw_tools.set_open (true);+		draw_tool_modifiers.set_open (true);+		edit_point_modifiers.set_open (true);+		path_tool_modifiers.set_open (true);+		view_tools.set_open (true);+		grid.set_open (true);+		characterset_tools.set_open (true);+		test_tools.set_open (true);+		guideline_tools.set_open (true);+		shape_tools.set_open (true);+		background_tools.set_open (true);+		style_tools.set_open (true);+		+		add_expander (draw_tools);+		add_expander (draw_tool_modifiers);+		add_expander (edit_point_modifiers);+		add_expander (path_tool_modifiers);	+		+		add_expander (characterset_tools);+		add_expander (guideline_tools);+		add_expander (grid);+		add_expander (view_tools);+		add_expander (shape_tools);+		add_expander (background_tools);+		add_expander (style_tools);+		+		// Fixa: add_expander (trace);+		+		add_expander (test_tools);+		+		draw_tools.set_persistent (true);+		draw_tools.set_unique (true);+		+		draw_tool_modifiers.set_persistent (true);+		draw_tool_modifiers.set_unique (true);++		edit_point_modifiers.set_persistent (false);+		edit_point_modifiers.set_unique (false);+		+		path_tool_modifiers.set_persistent (false);+		path_tool_modifiers.set_unique (false);++		characterset_tools.set_persistent (true);+		characterset_tools.set_unique (true);+		+		test_tools.set_persistent (true);+	+		guideline_tools.set_persistent (true);+		guideline_tools.set_unique (false);+		+		grid.set_persistent (true);+		grid.set_unique (true);+		grid.set_open (false);+		+		shape_tools.set_persistent (true);+		shape_tools.set_unique (true);+		+		background_tools.set_persistent (true);+		background_tools.set_unique (true);++		MainWindow.get_toolbox ().update_expanders ();+		MainWindow.get_toolbox ().reset_active_tool ();++		// Default selection+		var idle = new IdleSource();+		idle.set_callback (() => {+			pen_tool.set_selected (true);+			+			select_draw_tool ();			+			set_point_type_from_preferences ();+			+			if (GlyphCanvas.get_current_glyph ().get_show_help_lines ()) {+				help_lines.set_selected (true);+				help_lines.set_active (false);+			}++			add_new_grid ();+			add_new_grid ();+			+			MainWindow.get_toolbox ().move (0, 0);+			+			return false;+		});+		+		idle.attach (null);+	}++	public static void set_point_type_from_preferences () {+		string type = Preferences.get ("point_type");+		if (type == "double_points") {+			Toolbox.select_tool_by_name ("double_points");+		} else if (type == "quadratic_points") {+			Toolbox.select_tool_by_name ("quadratic_points");+		} if (type == "cubic_points") {+			Toolbox.select_tool_by_name ("cubic_points");+		}+	}+	+	public override unowned List<Expander> get_expanders () {+		return expanders;+	}+	+	/** Insert new points of this type. */+	public static PointType get_selected_point_type () {+		return point_type;+	}++	private void select_draw_tool () {+		Toolbox.select_tool_by_name ("pen_tool");+	}+	+	public void remove_all_grid_buttons () {+		while (grid_expander.tool.length () > 0) {+			grid_expander.tool.remove_link (grid_expander.tool.last ());+		}+		+		while (GridTool.sizes.length () > 0) {+			GridTool.sizes.remove_link (GridTool.sizes.first ());+		}+		+		grid_expander.set_open (true);+		MainWindow.get_toolbox ().update_expanders ();+		MainWindow.get_toolbox ().redraw (0, 0, allocation_width, allocation_height);		+	}+	+	public void parse_grid (string spin_button_value) {+		SpinButton sb = add_new_grid ();+		sb.set_value (spin_button_value);+		MainWindow.get_toolbox ().select_tool (sb);+	}++	public SpinButton add_new_grid () {+		SpinButton grid_width = new SpinButton ("grid_width", _("Set size for grid"));+		Toolbox tb = MainWindow.get_toolbox ();+		+		grid_width.new_value_action.connect((self) => {+			grid_width.select_action (grid_width);+		});++		grid_width.select_action.connect((self) => {+			SpinButton sb = (SpinButton) self;+			GridTool.set_grid_width (sb.get_value ());+			MainWindow.get_glyph_canvas ().redraw ();+		});+				+		grid_expander.add_tool (grid_width);++		GridTool.sizes.append (grid_width);++		grid_expander.set_open (true);+		tb.update_expanders ();+		+		tb.redraw (0, 0, allocation_width, allocation_height);+		+		tb.select_tool (grid_width);+		grid_width.set_active (false);+		+		return grid_width;+	}++	public void remove_current_grid () {+		Tool grid_width;+		Toolbox tb = MainWindow.get_toolbox ();+		+		foreach (Tool t in grid_expander.tool) {+			if (t.is_selected () && t is SpinButton) {+				GridTool.sizes.remove ((SpinButton)t);+				grid_expander.tool.remove (t);+				break;+			}+		}+		+		if (grid_expander.tool.length () > 0) {+			grid_width = grid_expander.tool.last ().data;+			tb.select_tool (grid_width);+			grid_width.set_active (false);+		}+		+		MainWindow.get_toolbox ().update_expanders ();+		tb.redraw (0, 0, allocation_width, allocation_height);+	}+	+	private void add_expander (Expander e) {+		expanders.append (e);+	}+}++}diff --git a/libbirdfont/KerningDisplay.vala b/libbirdfont/KerningDisplay.valaindex cdeda38..18d0f67 100644--- a/libbirdfont/KerningDisplay.vala+++ b/libbirdfont/KerningDisplay.vala@@ -259,12 +259,19 @@ public class KerningDisplay : FontDisplay { 		GlyphSequence word_with_ligatures; 		 		foreach (GlyphSequence word in row) {+			foreach (Glyph? g in word.glyph) {+				if (g == null) print ("null");+				else print (((!)g).get_name ());+				print ("\n");+			}+		}+		print ("\n");+		+		foreach (GlyphSequence word in row) { 			col_index = 0; 			 			word_with_ligatures = word.process_ligatures (); 			foreach (Glyph? g in word_with_ligatures.glyph) {-				// draw glyph- 				if (g == null) { 					w = 50;	 				} else {@@ -289,9 +296,11 @@ public class KerningDisplay : FontDisplay { 						active_handle = i - row_index; 						MainWindow.get_glyph_canvas ().redraw (); 					}-+					 					if (col_index == word.glyph.length () || col_index == 0) { 						active_handle = -1;+					} else {+						active_handle += row_index; 					} 				} 				diff --git a/libbirdfont/KerningTools.vala b/libbirdfont/KerningTools.valanew file mode 100644index 0000000..fecf062--- /dev/null+++ b/libbirdfont/KerningTools.vala@@ -0,0 +1,28 @@+/*+    Copyright (C) 2013 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 {++public class KerningTools : ToolCollection  {+	public List<Expander> expanders;+	+	public override unowned List<Expander> get_expanders () {+		return expanders;+	}+}++}diff --git a/libbirdfont/MainWindow.vala b/libbirdfont/MainWindow.valaindex 63e6f07..315e7e9 100644--- a/libbirdfont/MainWindow.vala+++ b/libbirdfont/MainWindow.vala@@ -41,6 +41,10 @@ public class MainWindow { 		over_view = new OverView();
 	}
 
+	public static DrawingTools get_drawing_tools () {
+		return tools.drawing_tools;
+	}
+
 	public void set_native (NativeWindow nw) {
 		native_window = nw;
 	}
diff --git a/libbirdfont/MenuTab.vala b/libbirdfont/MenuTab.valaindex e6cb174..9f951a2 100644--- a/libbirdfont/MenuTab.vala+++ b/libbirdfont/MenuTab.vala@@ -279,12 +279,12 @@ c.append (""" 				return; 			} 				-			MainWindow.get_toolbox ().remove_all_grid_buttons ();+			MainWindow.get_drawing_tools ().remove_all_grid_buttons (); 			foreach (string v in f.grid_width) {-				MainWindow.get_toolbox ().parse_grid (v);+				MainWindow.get_drawing_tools ().parse_grid (v); 			} 			-			MainWindow.get_toolbox ().background_scale.set_value (f.background_scale);+			MainWindow.get_drawing_tools ().background_scale.set_value (f.background_scale); 			 			select_overview (); 		});@@ -354,7 +354,7 @@ c.append (""" 		fn = f.get_path (); 		 		if (f.font_file != null && fn.has_suffix (".bf")) {-			f.background_scale = MainWindow.get_toolbox ().background_scale.get_display_value ();+			f.background_scale = MainWindow.get_drawing_tools ().background_scale.get_display_value (); 			 			while (f.grid_width.length () > 0) { 				f.grid_width.remove_link (f.grid_width.first ());@@ -387,9 +387,9 @@ c.append (""" 			BirdFont.new_font (); 			MainWindow.close_all_tabs (); 			-			MainWindow.get_toolbox ().remove_all_grid_buttons ();-			MainWindow.get_toolbox ().add_new_grid ();-			MainWindow.get_toolbox ().add_new_grid ();+			MainWindow.get_drawing_tools ().remove_all_grid_buttons ();+			MainWindow.get_drawing_tools ().add_new_grid ();+			MainWindow.get_drawing_tools ().add_new_grid (); 			 			select_overview (); 		});diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex 447646f..a47f408 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -2221,7 +2221,7 @@ public class Path { 	public void init_point_type () { 		PointType type; 		-		switch (Toolbox.point_type) {+		switch (DrawingTools.point_type) { 			case PointType.QUADRATIC: 				type = PointType.LINE_QUADRATIC; 				break;diff --git a/libbirdfont/PenTool.vala b/libbirdfont/PenTool.valaindex 273afd2..e69d1be 100644--- a/libbirdfont/PenTool.vala+++ b/libbirdfont/PenTool.vala@@ -240,7 +240,7 @@ public class PenTool : Tool { 	 	public void set_precision (double p) { 		precision = p;-		MainWindow.get_toolbox ().precision.set_value_round (p, false, false);+		DrawingTools.precision.set_value_round (p, false, false); 	} 	 	public void move (double x, double y) {@@ -944,11 +944,11 @@ public class PenTool : Tool { 			p.left_handle.type = PointType.QUADRATIC; 			p.right_handle.type = PointType.LINE_QUADRATIC; 			p.type = PointType.QUADRATIC;-		} else if (Toolbox.get_selected_point_type () == PointType.QUADRATIC) {+		} else if (DrawingTools.get_selected_point_type () == PointType.QUADRATIC) { 			p.left_handle.type = PointType.LINE_QUADRATIC; 			p.right_handle.type = PointType.LINE_QUADRATIC; 			p.type = PointType.LINE_QUADRATIC;-		} else if (Toolbox.get_selected_point_type () == PointType.DOUBLE_CURVE) {+		} else if (DrawingTools.get_selected_point_type () == PointType.DOUBLE_CURVE) { 			p.left_handle.type = PointType.LINE_DOUBLE_CURVE; 			p.right_handle.type = PointType.LINE_DOUBLE_CURVE; 			p.type = PointType.DOUBLE_CURVE;@@ -1401,7 +1401,7 @@ public class PenTool : Tool { 	}  	public static PointType to_line (PointType t) {-		switch (Toolbox.point_type) {+		switch (DrawingTools.point_type) { 			case PointType.QUADRATIC: 				return PointType.LINE_QUADRATIC; 			case PointType.DOUBLE_CURVE:@@ -1415,32 +1415,32 @@ public class PenTool : Tool { 	} 	 	public static void set_converted_handle_length (EditPointHandle e) {-		if (e.type == PointType.QUADRATIC  && Toolbox.point_type == PointType.DOUBLE_CURVE) {+		if (e.type == PointType.QUADRATIC  && DrawingTools.point_type == PointType.DOUBLE_CURVE) { 			e.length *= 2; 			e.length /= 4; 		} -		if (e.type == PointType.QUADRATIC  && Toolbox.point_type == PointType.CUBIC) {+		if (e.type == PointType.QUADRATIC  && DrawingTools.point_type == PointType.CUBIC) { 			e.length *= 2; 			e.length /= 3; 		} -		if (e.type == PointType.DOUBLE_CURVE  && Toolbox.point_type == PointType.QUADRATIC) {+		if (e.type == PointType.DOUBLE_CURVE  && DrawingTools.point_type == PointType.QUADRATIC) { 			e.length *= 4; 			e.length /= 2;			 		} -		if (e.type == PointType.DOUBLE_CURVE  && Toolbox.point_type == PointType.CUBIC) {+		if (e.type == PointType.DOUBLE_CURVE  && DrawingTools.point_type == PointType.CUBIC) { 			e.length *= 4; 			e.length /= 3;		 		} -		if (e.type == PointType.CUBIC  && Toolbox.point_type == PointType.QUADRATIC) {+		if (e.type == PointType.CUBIC  && DrawingTools.point_type == PointType.QUADRATIC) { 			e.length *= 3; 			e.length /= 2;		 		} -		if (e.type == PointType.CUBIC  && Toolbox.point_type == PointType.DOUBLE_CURVE) {+		if (e.type == PointType.CUBIC  && DrawingTools.point_type == PointType.DOUBLE_CURVE) { 			e.length *= 3; 			e.length /= 4;			 		}		@@ -1478,21 +1478,21 @@ public class PenTool : Tool { 			set_converted_handle_length (e.get_next ().data.get_left_handle ()); 														 			if (!is_line (e.type)) {-				e.type = Toolbox.point_type;+				e.type = DrawingTools.point_type; 			} else {-				e.type = to_line (Toolbox.point_type);+				e.type = to_line (DrawingTools.point_type); 			} 			 			if (!is_line (e.get_right_handle ().type)) {-				e.get_right_handle ().type = Toolbox.point_type;+				e.get_right_handle ().type = DrawingTools.point_type; 			} else {-				e.get_right_handle ().type = to_line (Toolbox.point_type);+				e.get_right_handle ().type = to_line (DrawingTools.point_type); 			}  			if (!is_line (e.type)) {-				e.get_next ().data.get_left_handle ().type = Toolbox.point_type;+				e.get_next ().data.get_left_handle ().type = DrawingTools.point_type; 			} else {-				e.get_next ().data.get_left_handle ().type = to_line (Toolbox.point_type);+				e.get_next ().data.get_left_handle ().type = to_line (DrawingTools.point_type); 			} 				 			// process connected handlediff --git a/libbirdfont/ToolCollection.vala b/libbirdfont/ToolCollection.valanew file mode 100644index 0000000..59a1495--- /dev/null+++ b/libbirdfont/ToolCollection.vala@@ -0,0 +1,24 @@+/*+    Copyright (C) 2013 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 {++public abstract class ToolCollection : GLib.Object  {+	public abstract unowned List<Expander> get_expanders ();+}++}diff --git a/libbirdfont/Toolbox.vala b/libbirdfont/Toolbox.valaindex cae5591..1cb4d96 100644--- a/libbirdfont/Toolbox.vala+++ b/libbirdfont/Toolbox.vala@@ -18,23 +18,14 @@ using Math; namespace BirdFont {  public class Toolbox : GLib.Object  {-	GlyphCanvas glyph_canvas;+	ToolCollection current_set;  	-	public List<Expander> expanders;+	public DrawingTools drawing_tools;+	public KerningTools kerning_tools; 	 	Tool current_tool = new Tool ("no_icon"); 	-	Expander draw_tools;-	Expander grid_expander;-	Expander shape_tools;-	-	BackgroundTool move_background;-	CutBackgroundTool cut_background;-	-	public Tool press_tool = new Tool (null); // activate the pressed button on release-	-	public SpinButton background_scale = new SpinButton ();-	public SpinButton precision;+	public Tool press_tool = new Tool (null); 	 	public signal void redraw (int x, int y, int w, int h); 	@@ -43,669 +34,28 @@ public class Toolbox : GLib.Object  { 	 	ImageSurface? toolbox_background = null; 	-	public static PointType point_type = PointType.DOUBLE_CURVE;-	-	public Toolbox (GlyphCanvas main_glyph_canvas) {-		glyph_canvas = main_glyph_canvas;-+	public Toolbox (GlyphCanvas glyph_canvas) {+		drawing_tools = new DrawingTools (glyph_canvas);+		kerning_tools = new KerningTools ();+		current_set = drawing_tools; 		toolbox_background = Icons.get_icon ("toolbox_background.png");-		-		draw_tools = new Expander ();-		shape_tools = new Expander ();-			-		Expander path_tool_modifiers = new Expander ();-		Expander draw_tool_modifiers = new Expander ();-		Expander edit_point_modifiers = new Expander ();-		Expander characterset_tools = new Expander ();-		Expander test_tools = new Expander ();-		Expander guideline_tools = new Expander ();-		Expander view_tools = new Expander ();-		Expander grid = new Expander ();-		-		Expander background_tools = new Expander ();-		Expander style_tools = new Expander ();-		-		grid_expander = grid;--		// Draw tools-		PenTool pen_tool = new PenTool ("pen_tool");-		draw_tools.add_tool (pen_tool);-	-		ZoomTool zoom_tool = new ZoomTool ("zoom_tool");-		draw_tools.add_tool (zoom_tool);--		Tool move_tool = new MoveTool ("move");-		draw_tools.add_tool (move_tool);--		// quadratic Bézier points-		Tool quadratic_points = new Tool ("quadratic_points", _("Create quadratic Bézier curves"));-		quadratic_points.select_action.connect ((self) => {-			point_type = PointType.QUADRATIC;-			Preferences.set ("point_type", "quadratic_points");-		});-		draw_tool_modifiers.add_tool (quadratic_points);		--		// cubic Bézier points-		Tool cubic_points = new Tool ("cubic_points", _("Create cubic Bézier curves"));-		cubic_points.select_action.connect ((self) => {-			point_type = PointType.CUBIC;-			Preferences.set ("point_type", "cubic_points");-		});-		draw_tool_modifiers.add_tool (cubic_points);--		// two quadratic points off curve points for each quadratic control point-		Tool double_points = new Tool ("double_points", _("Quadratic path with two line handles"));-		double_points.select_action.connect ((self) => {-			point_type = PointType.DOUBLE_CURVE;-			Preferences.set ("point_type", "double_points");-		});-		draw_tool_modifiers.add_tool (double_points);--		// convert point-		Tool convert_points = new Tool ("convert_point", _("Convert selected points"));-		convert_points.select_action.connect ((self) => {-			PenTool.convert_point_types ();-			MainWindow.get_current_glyph ().update_view ();-		});-		convert_points.set_persistent (false);-		draw_tool_modifiers.add_tool (convert_points);--		// tie edit point handles-		Tool tie_handles = new Tool ("tie_point", _("Tie curve handles for the selected edit point"), 'w');-		tie_handles.select_action.connect ((self) => {-			bool tie;-			-			foreach (EditPoint ep in PenTool.selected_points) {-				tie = !ep.tie_handles;-				-				if (tie) {-					ep.process_tied_handle ();-					ep.set_reflective_handles (false);-				}-			-				ep.set_tie_handle (tie);-			}-			-			MainWindow.get_current_glyph ().update_view ();-		});-		edit_point_modifiers.add_tool (tie_handles);-		-		// symmetrical handles-		Tool reflect_handle = new Tool ("symmetric", _("Symmetrical handles"), 'r');-		reflect_handle.select_action.connect ((self) => {-			bool symmetrical;-			EditPoint ep;-			if (PenTool.selected_points.length () > 0) {-				ep = PenTool.selected_points.first ().data;-				symmetrical = ep.reflective_handles;-				foreach (EditPoint p in PenTool.selected_points) {-					p.set_reflective_handles (!symmetrical);-					p.process_symmetrical_handles ();-					-					if (symmetrical) {-						ep.set_tie_handle (false);-					}-				}-				-				MainWindow.get_current_glyph ().update_view ();-			}-		});-		edit_point_modifiers.add_tool (reflect_handle);--		Tool create_line = new Tool ("create_line", _("Convert segment to line."), 'r');-		create_line.select_action.connect ((self) => {-			PenTool.convert_segment_to_line ();-			MainWindow.get_current_glyph ().update_view ();-		});-		edit_point_modifiers.add_tool (create_line);-	-		// path tools-		Tool union_paths_tool = new Tool ("union_paths", _("Merge paths"));-		union_paths_tool.select_action.connect ((self) => {-			Glyph g = MainWindow.get_current_glyph ();-			g.merge_all ();-		});-		path_tool_modifiers.add_tool (union_paths_tool);-		-		Tool reverse_path_tool = new Tool ("reverse_path", _("Create counter from outline"));-		reverse_path_tool.select_action.connect ((self) => {-			Glyph g = MainWindow.get_current_glyph ();-			-			foreach (Path p in g.active_paths) {-				p.reverse ();-			}-		-			g.redraw_area (0, 0, g.allocation.width, g.allocation.height);-		});-		path_tool_modifiers.add_tool (reverse_path_tool);--		Tool move_layer = new Tool ("move_layer", _("Move to path to the bottom layer"), 'd');-		move_layer.select_action.connect ((self) => {-			Glyph g = MainWindow.get_current_glyph ();--			foreach (Path p in g.active_paths) {-				g.path_list.remove (p);-				g.path_list.prepend (p);-			}-		});-		path_tool_modifiers.add_tool (move_layer);--		Tool flip_vertical = new Tool ("flip_vertical", _("Flip path vertically"));-		flip_vertical.select_action.connect ((self) => {-			MoveTool.flip_vertical ();-			MainWindow.get_current_glyph ().update_view ();-		});-		path_tool_modifiers.add_tool (flip_vertical);--		Tool flip_horizontal = new Tool ("flip_horizontal", _("Flip path horizontally"));-		flip_horizontal.select_action.connect ((self) => {-			MoveTool.flip_horizontal ();-			MainWindow.get_current_glyph ().update_view ();-		});-		path_tool_modifiers.add_tool (flip_horizontal);-		-		// adjust precision-		string precision_value = Preferences.get ("precision");-		-		precision = new SpinButton ("precision", _("Set precision"));-		-		if (precision_value != "") {-			precision.set_value (precision_value);-		} else {-			precision.set_value_round (1);-		}-		-		precision.new_value_action.connect ((self) => {-			select_tool (precision);-			-			Preferences.set ("precision", self.get_display_value ());-			redraw ((int) precision.x, (int) precision.y, 70, 70);-		});--		precision.select_action.connect((self) => {-			pen_tool.set_precision (((SpinButton)self).get_value ());-		});-		-		precision.set_min (0.001);-		precision.set_max (1);-		-		path_tool_modifiers.add_tool (precision);-		-		// Character set tools-		Tool full_unicode = new Tool ("utf_8", _("Show full unicode characters set"), 'f', CTRL);-		full_unicode.select_action.connect ((self) => {-				MainWindow.get_tab_bar ().add_unique_tab (new OverView (), 100, false);	-				OverView o = MainWindow.get_overview ();-				GlyphRange gr = new GlyphRange ();-				-				if (!BirdFont.get_current_font ().initialised) {-					MenuTab.new_file ();-				}-				-				DefaultCharacterSet.use_full_unicode_range (gr);-				o.set_glyph_range (gr);-				MainWindow.get_tab_bar ().select_tab_name ("Overview");-			});-		characterset_tools.add_tool (full_unicode);--		Tool custom_character_set = new Tool ("custom_character_set", _("Show default characters set"), 'r', CTRL);-		custom_character_set.select_action.connect ((self) => {-			MainWindow.get_tab_bar ().add_unique_tab (new OverView (), 100, false);-			OverView o = MainWindow.get_overview ();-			GlyphRange gr = new GlyphRange ();--			if (!BirdFont.get_current_font ().initialised) {-				MenuTab.new_file ();-			}-			-			DefaultCharacterSet.use_default_range (gr);-			o.set_glyph_range (gr);-			MainWindow.get_tab_bar ().select_tab_name ("Overview");-		});-		characterset_tools.add_tool (custom_character_set);--		Tool avalilable_characters = new Tool ("available_characters", _("Show all characters in the font"), 'd', CTRL);-		avalilable_characters.select_action.connect ((self) => {-			MainWindow.get_tab_bar ().add_unique_tab (new OverView (), 100, false);-			OverView o = MainWindow.get_overview ();-			-			if (!BirdFont.get_current_font ().initialised) {-				MenuTab.new_file ();-			}-			-			o.display_all_available_glyphs ();-			MainWindow.get_tab_bar ().select_tab_name ("Overview");-		});-		characterset_tools.add_tool (avalilable_characters);--		Tool delete_glyph = new Tool ("delete_selected_glyph", _("Delete selected glyph"));-		delete_glyph.select_action.connect ((self) => {-			OverView o = MainWindow.get_overview ();-			-			if (MainWindow.get_current_display () is OverView) {-				o.delete_selected_glyph ();-			}-			-			MainWindow.get_tab_bar ().select_tab_name ("Overview");-		});-		characterset_tools.add_tool (delete_glyph);--		if (BirdFont.has_argument ("--test")) {-			Tool test_case = new Tool ("test_case");-			test_case.select_action.connect((self) => {-					if (self.is_selected ()) {-						if (TestBirdFont.is_running ()) {-							TestBirdFont.pause ();-						} else {-							TestBirdFont.continue ();-						}-					}-				});-			test_tools.add_tool (test_case);--			Tool slow_test = new Tool ("slow_test");-			slow_test.select_action.connect((self) => {-					bool s = TestBirdFont.is_slow_test ();-					TestBirdFont.set_slow_test (!s);-					s = TestBirdFont.is_slow_test ();-					self.set_selected (s);-				});-		-			test_tools.add_tool (slow_test);-					-			// Run from commad line-			string? st = BirdFont.get_argument ("--test");-			if (st != null && ((!)st).char_count () > 0) {-				IdleSource idle = new IdleSource ();--				idle.set_callback (() => {			-					select_tool (test_case);-					return false;-				});-				-				idle.attach (null);-			}-			-			if (BirdFont.has_argument ("--slow")) {-				select_tool (slow_test);-			}-			-		}-		-		// guide lines, grid and other guidlines-		Tool help_lines = new Tool ("help_lines", _("Show guidelines"), 'l');-		help_lines.select_action.connect ((self) => {-				bool h;-				h = GlyphCanvas.get_current_glyph ().get_show_help_lines ();-				GlyphCanvas.get_current_glyph ().set_show_help_lines (!h);-				self.set_selected (!h);-				GlyphCanvas.get_current_glyph ().redraw_help_lines ();-			});	--		guideline_tools.add_tool (help_lines);--		Tool xheight_help_lines = new Tool ("show_xheight_helplines", _("Show guidelines for x-height and baseline"), 'x');-		xheight_help_lines.select_action.connect ((self) => {-			Glyph g = MainWindow.get_current_glyph ();-			bool v = !g.get_xheight_lines_visible ();-			g.set_xheight_lines_visible (v);-			self.set_selected (v);-			MainWindow.get_glyph_canvas ().redraw ();-			-			if (v && !help_lines.is_selected ()) {-				select_tool (help_lines);-			}-			-		});-		guideline_tools.add_tool (xheight_help_lines);--		Tool background_help_lines = new Tool ("background_help_lines", _("Show guidelines at top and bottom margin"), 't');-		background_help_lines.select_action.connect ((self) => {-			Glyph g = MainWindow.get_current_glyph ();-			bool v = !g.get_margin_lines_visible ();-			g.set_margin_lines_visible (v);-			self.set_selected (v);-			MainWindow.get_glyph_canvas ().redraw ();-			-			if (v && !help_lines.is_selected ()) {-				select_tool (help_lines);-			}-		});-		guideline_tools.add_tool (background_help_lines);--		Tool new_grid = new GridTool ("new_grid");-		guideline_tools.add_tool (new_grid);--		// Zoom tools -		Tool zoom_in = new Tool ("zoom_in", _("Zoom in"), '+', CTRL);-		zoom_in.select_action.connect ((self) => {-			zoom_tool.store_current_view ();-			glyph_canvas.get_current_display ().zoom_in ();-		});-		view_tools.add_tool (zoom_in);--		Tool zoom_out = new Tool ("zoom_out", _("Zoom out"), '-', CTRL);-		zoom_out.select_action.connect ((self) => {-			zoom_tool.store_current_view ();-			glyph_canvas.get_current_display ().zoom_out ();-		});-		view_tools.add_tool (zoom_out);--		Tool reset_zoom = new Tool ("zoom_1_1", _("Zoom to scale 1:1"), '0', CTRL);-		reset_zoom.select_action.connect ((self) => {-				zoom_tool.store_current_view ();-				glyph_canvas.get_current_display ().reset_zoom ();-				glyph_canvas.redraw_area(0, 0, glyph_canvas.allocation.width, glyph_canvas.allocation.height);-			});-		view_tools.add_tool (reset_zoom);--		Tool full_glyph = new Tool ("full_glyph", _("Show full glyph"));-		full_glyph.select_action.connect((self) => {-			zoom_tool.store_current_view ();-			zoom_tool.zoom_full_glyph ();-		});-		view_tools.add_tool (full_glyph);--		Tool zoom_boundries = new Tool ("zoom_boundries", _("Zoom in at region boundries"), 'v');-		zoom_boundries.select_action.connect((self) => {-			zoom_tool.store_current_view ();-			glyph_canvas.get_current_display ().zoom_max ();-		});-		view_tools.add_tool (zoom_boundries);--		Tool zoom_bg = new Tool ("zoom_background_image", _("Zoom in background image"));-		zoom_bg.select_action.connect((self) => {-			if (MainWindow.get_current_glyph ().get_background_image () != null) {-				zoom_tool.store_current_view ();					-				glyph_canvas.get_current_display ().reset_zoom ();-				-				zoom_tool.zoom_full_background_image ();-				-				glyph_canvas.redraw_area(0, 0, glyph_canvas.allocation.width, glyph_canvas.allocation.height);-			}-		});-		view_tools.add_tool (zoom_bg);--		Tool zoom_prev = new Tool ("prev", _("Previous view"), 'j', CTRL);-		zoom_prev.select_action.connect((self) => {-			zoom_tool.previous_view ();-		});-		view_tools.add_tool (zoom_prev);--		Tool zoom_next = new Tool ("next", _("Next view"), 'l', CTRL);-		zoom_next.select_action.connect((self) => {-			zoom_tool.next_view ();-		});-		view_tools.add_tool (zoom_next);-		-		// shape tools -		Tool circle = new CircleTool ("circle");-		shape_tools.add_tool (circle);-		-		Tool rectangle = new RectangleTool ("rectangle");-		shape_tools.add_tool (rectangle);-				-		// background tools-		background_scale = new SpinButton ("scale_background", _("Set size for background image"));-		background_scale.set_int_value ("1.000");-		-		background_scale.new_value_action.connect((self) => {-			background_scale.select_action (self);-		});-		-		background_scale.select_action.connect((self) => {-			SpinButton sb = (SpinButton) self;-			Glyph g = MainWindow.get_current_glyph ();-			GlyphBackgroundImage? img = g.get_background_image ();-			double s = sb.get_value ();-			-			if (img != null) {-				((!)img).set_img_scale (s, s);-			}-			-			MainWindow.get_glyph_canvas ().redraw ();-		});-		-		background_tools.add_tool (background_scale);		--		BackgroundTool move_background = new BackgroundTool ("move_background");			-		background_tools.add_tool (move_background);-		this.move_background = move_background;-		-		CutBackgroundTool cut_background = new CutBackgroundTool ("cut_background");-		background_tools.add_tool (cut_background);-		this.cut_background = cut_background;-		-		Tool show_bg = new Tool ("show_background", _("Show/hide background image"));-		show_bg.select_action.connect ((self) => {-			Glyph g = MainWindow.get_current_glyph ();-			g.set_background_visible (!g.get_background_visible ());-			MainWindow.get_glyph_canvas ().redraw ();-		});-		background_tools.add_tool (show_bg);--		Tool bg_selection = new Tool ("insert_background", _("Insert a new background image"));-		bg_selection.select_action.connect((self) => {-			Glyph? g = null;-			FontDisplay fd = MainWindow.get_current_display ();-			TooltipArea tp = MainWindow.get_tool_tip ();-			tp.show_text (_("Creating thumbnails"));-			-			Tool.yield ();-		-			if (fd is Glyph) {-				g = (Glyph) fd;-			} else {-				return;-			}-			-			BackgroundSelection bgs = new BackgroundSelection ();-			MainWindow.get_tab_bar ().add_unique_tab (bgs , 120, false);-			-			tp.show_text ("");-		});-		-		bg_selection.set_show_background (true);-		background_tools.add_tool (bg_selection);-		-		SpinButton background_contrast = new SpinButton ("background_contrast", _("Set contrast for background image"));-		background_contrast.set_value_round (1);--		background_contrast.new_value_action.connect ((self) => {-			background_contrast.select_action (self);-		});-		-		background_contrast.select_action.connect ((self) => {		-			Glyph g = MainWindow.get_current_glyph ();-			GlyphBackgroundImage? bg = g.get_background_image ();-			GlyphBackgroundImage b;-			-			if (bg != null) {-				b = (!) bg;-				b.set_contrast (background_contrast.get_value ());-			}-		});--		// color and style-		ColorTool stroke_color = new ColorTool (_("Stroke color"));-		stroke_color.color_updated.connect (() => {-			Path.line_color_r = stroke_color.color_r;-			Path.line_color_g = stroke_color.color_g;-			Path.line_color_b = stroke_color.color_b;-			Path.line_color_a = stroke_color.color_a;--			Preferences.set ("line_color_r", @"$(Path.line_color_r)");-			Preferences.set ("line_color_g", @"$(Path.line_color_g)");-			Preferences.set ("line_color_b", @"$(Path.line_color_b)");-			Preferences.set ("line_color_a", @"$(Path.line_color_a)");--			Glyph g = MainWindow.get_current_glyph ();-			g.redraw_area (0, 0, g.allocation.width, g.allocation.height);-		});-		stroke_color.set_r (double.parse (Preferences.get ("line_color_r")));-		stroke_color.set_g (double.parse (Preferences.get ("line_color_g")));-		stroke_color.set_b (double.parse (Preferences.get ("line_color_b")));-		stroke_color.set_a (double.parse (Preferences.get ("line_color_a")));-		style_tools.add_tool (stroke_color);-		-		SpinButton stroke_width;-		stroke_width = new SpinButton ("stroke_width", _("Stroke width"));-		-		if (Preferences.get ("stroke_width") == "") {-			stroke_width.set_value_round (1);-		} else {-			stroke_width.set_value (Preferences.get ("stroke_width"));-		}-		-		stroke_width.new_value_action.connect((self) => {-			Glyph g = MainWindow.get_current_glyph ();-			Path.stroke_width = stroke_width.get_value ();-			g.redraw_area (0, 0, g.allocation.width, g.allocation.height);-			Preferences.set ("stroke_width", @"$(Path.stroke_width)");-			redraw ((int) stroke_width.x, (int) stroke_width.y, 70, 70);-		});-		style_tools.add_tool (stroke_width);--		ColorTool handle_color = new ColorTool (_("Handle color"));-		handle_color.color_updated.connect (() => {-			Path.handle_color_r = handle_color.color_r;-			Path.handle_color_g = handle_color.color_g;-			Path.handle_color_b = handle_color.color_b;-			Path.handle_color_a = handle_color.color_a;--			Preferences.set ("handle_color_r", @"$(Path.handle_color_r)");-			Preferences.set ("handle_color_g", @"$(Path.handle_color_g)");-			Preferences.set ("handle_color_b", @"$(Path.handle_color_b)");-			Preferences.set ("handle_color_a", @"$(Path.handle_color_a)");--			Glyph g = MainWindow.get_current_glyph ();-			g.redraw_area (0, 0, g.allocation.width, g.allocation.height);-		});-		handle_color.set_r (double.parse (Preferences.get ("handle_color_r")));-		handle_color.set_g (double.parse (Preferences.get ("handle_color_g")));-		handle_color.set_b (double.parse (Preferences.get ("handle_color_b")));-		handle_color.set_a (double.parse (Preferences.get ("handle_color_a")));-		style_tools.add_tool (handle_color);-		-		draw_tools.set_open (true);-		draw_tool_modifiers.set_open (true);-		edit_point_modifiers.set_open (true);-		path_tool_modifiers.set_open (true);-		view_tools.set_open (true);-		grid.set_open (true);-		characterset_tools.set_open (true);-		test_tools.set_open (true);-		guideline_tools.set_open (true);-		shape_tools.set_open (true);-		background_tools.set_open (true);-		style_tools.set_open (true);-		-		add_expander (draw_tools);-		add_expander (draw_tool_modifiers);-		add_expander (edit_point_modifiers);-		add_expander (path_tool_modifiers);	-		-		add_expander (characterset_tools);-		add_expander (guideline_tools);-		add_expander (grid);-		add_expander (view_tools);-		add_expander (shape_tools);-		add_expander (background_tools);-		add_expander (style_tools);-		-		// Fixa: add_expander (trace);-		-		add_expander (test_tools);-		-		draw_tools.set_persistent (true);-		draw_tools.set_unique (true);-		-		draw_tool_modifiers.set_persistent (true);-		draw_tool_modifiers.set_unique (true);--		edit_point_modifiers.set_persistent (false);-		edit_point_modifiers.set_unique (false);-		-		path_tool_modifiers.set_persistent (false);-		path_tool_modifiers.set_unique (false);--		characterset_tools.set_persistent (true);-		characterset_tools.set_unique (true);-		-		test_tools.set_persistent (true);-	-		guideline_tools.set_persistent (true);-		guideline_tools.set_unique (false);-		-		grid.set_persistent (true);-		grid.set_unique (true);-		grid.set_open (false);-		-		shape_tools.set_persistent (true);-		shape_tools.set_unique (true);-		-		background_tools.set_persistent (true);-		background_tools.set_unique (true);--		update_expanders ();-		reset_active_tool ();--		// Default selection-		var idle = new IdleSource();-		idle.set_callback (() => {-			pen_tool.set_selected (true);-			-			select_draw_tool ();			-			set_point_type_from_preferences ();-			-			if (GlyphCanvas.get_current_glyph ().get_show_help_lines ()) {-				help_lines.set_selected (true);-				help_lines.set_active (false);-			}--			add_new_grid ();-			add_new_grid ();-			-			move (0, 0);-			-			return false;-		});-		-		idle.attach (null); 	} -	public static void set_point_type_from_preferences () {-		string type = Preferences.get ("point_type");-		print (type);-		print ("\n");-		if (type == "double_points") {-			Toolbox.select_tool_by_name ("double_points");-		} else if (type == "quadratic_points") {-			Toolbox.select_tool_by_name ("quadratic_points");-		} if (type == "cubic_points") {-			Toolbox.select_tool_by_name ("cubic_points");-		}-	}-	-	/** Insert new points of this type. */-	public static PointType get_selected_point_type () {-		return point_type;-	}-	+ 	public void key_press (uint keyval) {-		foreach (var exp in MainWindow.get_toolbox ().expanders) {+		foreach (Expander exp in current_set.get_expanders ()) { 			foreach (Tool t in exp.tool) { 				t.set_active (false); 				 				if (t.key == keyval && t.modifier_flag == NONE && KeyBindings.modifier == NONE) {-					MainWindow.get_toolbox ().select_tool (t);+					select_tool (t); 				} 			} 		} 	} 	 	public void press (uint button, double x, double y) {-		foreach (var exp in expanders) {+		foreach (Expander exp in current_set.get_expanders ()) { 			foreach (Tool t in exp.tool) { 				if (t.is_over (x, y)) { 					t.panel_press_action (t, button, x, y);@@ -716,7 +66,7 @@ public class Toolbox : GLib.Object  { 	} 	 	public void release (uint button, double x, double y) {-		foreach (var exp in expanders) {+		foreach (Expander exp in current_set.get_expanders ()) { 			if (exp.is_over (x, y)) { 				exp.set_open (! exp.is_open ());					 				update_expanders ();			@@ -740,7 +90,7 @@ public class Toolbox : GLib.Object  { 	}  	public void scroll_up (double x, double y) {-		foreach (var exp in expanders) {+		foreach (Expander exp in current_set.get_expanders ()) { 			foreach (Tool t in exp.tool) { 				if (t.is_over (x, y)) { 					t.scroll_wheel_up_action (t);@@ -751,7 +101,7 @@ public class Toolbox : GLib.Object  { 	}  	public void scroll_down (double x, double y) {-		foreach (var exp in expanders) {+		foreach (Expander exp in current_set.get_expanders ()) { 			foreach (Tool t in exp.tool) { 				if (t.is_over (x, y)) { 					t.scroll_wheel_down_action (t);@@ -760,15 +110,11 @@ public class Toolbox : GLib.Object  { 			} 		} 	}-		-	private void select_draw_tool () {-		select_tool_by_name ("pen_tool");-	} 	 	public void move (double x, double y) { 		bool update; 		bool a;-		foreach (var exp in expanders) {+		foreach (Expander exp in current_set.get_expanders ()) { 			a = exp.is_over (x, y); 			update = exp.set_active (a); 			@@ -797,78 +143,9 @@ public class Toolbox : GLib.Object  { 			} 		} 	}-	-	public void remove_all_grid_buttons () {-		while (grid_expander.tool.length () > 0) {-			grid_expander.tool.remove_link (grid_expander.tool.last ());-		}-		-		while (GridTool.sizes.length () > 0) {-			GridTool.sizes.remove_link (GridTool.sizes.first ());-		}-		-		grid_expander.set_open (true);-		update_expanders ();-		redraw (0, 0, allocation_width, allocation_height);		-	}-	-	public void parse_grid (string spin_button_value) {-		SpinButton sb = add_new_grid ();-		sb.set_value (spin_button_value);-		select_tool (sb);-	}--	public SpinButton add_new_grid () {-		SpinButton grid_width = new SpinButton ("grid_width", _("Set size for grid"));-		-		grid_width.new_value_action.connect((self) => {-			grid_width.select_action (grid_width);-		});--		grid_width.select_action.connect((self) => {-			SpinButton sb = (SpinButton) self;-			GridTool.set_grid_width (sb.get_value ());-			MainWindow.get_glyph_canvas ().redraw ();-		});-				-		grid_expander.add_tool (grid_width);--		GridTool.sizes.append (grid_width);--		grid_expander.set_open (true);-		update_expanders ();-		-		redraw (0, 0, allocation_width, allocation_height);-		-		select_tool (grid_width);-		grid_width.set_active (false);-		-		return grid_width;-	}--	public void remove_current_grid () {-		Tool grid_width;-		-		foreach (Tool t in grid_expander.tool) {-			if (t.is_selected () && t is SpinButton) {-				GridTool.sizes.remove ((SpinButton)t);-				grid_expander.tool.remove (t);-				break;-			}-		}-		-		if (grid_expander.tool.length () > 0) {-			grid_width = grid_expander.tool.last ().data;-			select_tool (grid_width);-			grid_width.set_active (false);-		}-		-		update_expanders ();-		redraw (0, 0, allocation_width, allocation_height);-	}  	public void reset_active_tool () {-		foreach (var exp in expanders) {+		foreach (Expander exp in current_set.get_expanders ()) { 			foreach (Tool t in exp.tool) { 				t.set_active (false); 			}@@ -876,7 +153,7 @@ public class Toolbox : GLib.Object  { 	}  	public Tool? get_active_tool () {-		foreach (var exp in expanders) {+		foreach (Expander exp in current_set.get_expanders ()) { 			foreach (Tool t in exp.tool) { 				if (t.is_active ()) { 					return t;@@ -892,8 +169,7 @@ public class Toolbox : GLib.Object  { 	} 	 	public void select_tool (Tool tool) {-		foreach (var exp in expanders) {-			+		foreach (Expander exp in current_set.get_expanders ()) { 			foreach (Tool t in exp.tool) { 				if (tool.get_id () == t.get_id ()) { 					exp.set_open (true);@@ -905,14 +181,15 @@ public class Toolbox : GLib.Object  { 						update = tool.set_active (true); 					} 					-					tool.select_action (tool); // execute command+					tool.select_action (tool); 					 					if (update) {							 						redraw ((int) exp.x - 10, (int) exp.y - 10, allocation_width, (int) (allocation_height - exp.y + 10)); 					} 					-					if (tool.persistent && exp == draw_tools || t == move_background -						|| t == cut_background || exp == shape_tools) {+					// FIXME: Set persistent to false for && exp == draw_tools || t == move_background +					//	|| t == cut_background || exp == shape_tool +					if (tool.persistent) { 						current_tool = tool; 					} 				}@@ -922,7 +199,7 @@ public class Toolbox : GLib.Object  { 	} 	 	public Tool get_tool (string name) {-		foreach (var e in expanders) {+		foreach (Expander e in current_set.get_expanders ()) { 			foreach (var t in e.tool) { 				if (t.get_name () == name) { 					return t;@@ -930,9 +207,10 @@ public class Toolbox : GLib.Object  { 			} 		} -		if (name == cut_background.get_name ()) {-			return cut_background;-		}+		// FIXME:+		//if (name == cut_background.get_name ()) {+		//	return cut_background;+		//} 				 		warning ("No tool found for name \"%s\".\n", name); 		@@ -949,10 +227,10 @@ public class Toolbox : GLib.Object  { 		b.select_tool (b.get_tool (name)); 	} 		-	private void update_expanders () {+	public void update_expanders () { 		Expander? p = null;  		Expander pp;-		foreach (var e in expanders) {+		foreach (Expander e in current_set.get_expanders ()) { 			if (p != null) { 				pp = (!) p; 				e.set_offset (pp.y + pp.margin + 12);@@ -962,12 +240,8 @@ public class Toolbox : GLib.Object  { 		} 	} 	-	private void add_expander (Expander e) {-		expanders.append (e);-	}-	 	private void draw_expanders (int w, int h, Context cr) {-		foreach (Expander e in expanders) {+		foreach (Expander e in current_set.get_expanders ()) { 			e.draw (w, h, cr); 			if (e.is_open ()) { 				e.draw_content (w, h, cr);@@ -999,17 +273,4 @@ public class Toolbox : GLib.Object  { 	} } -class ToolboxExpander : Expander {-	-	public ToolboxExpander () {-	}-	-	public override bool set_open (bool o) {-		bool r = (open != o);-		rotation = (o) ? 0 : Math.PI;-		open = o;-		return r;-	}-}- }

Contact

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