The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

BackgroundTool.vala in libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/BackgroundTool.vala.
Cache overview items
1 /* 2 Copyright (C) 2012 2014 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using Cairo; 16 17 namespace BirdFont { 18 19 public class BackgroundTool : Tool { 20 21 double begin_x = 0; 22 double begin_y = 0; 23 24 int last_x; 25 int last_y; 26 27 public double img_offset_x = 0; 28 public double img_offset_y = 0; 29 30 public double img_width = 0; 31 public double img_height = 0; 32 33 public double img_scale_x = 0; 34 35 public static double top_limit; 36 public static double bottom_limit; 37 38 bool move_bg; 39 40 static BackgroundImage imported_background; 41 static ImageSurface imported_surface; 42 43 public BackgroundTool (string name) { 44 base (name, t_("Move, resize and rotate background image")); 45 46 top_limit = 0; 47 bottom_limit = 0; 48 49 imported_background = new BackgroundImage (""); 50 51 select_action.connect((self) => { 52 }); 53 54 deselect_action.connect ((self) => { 55 }); 56 57 press_action.connect((self, b, x, y) => { 58 Glyph g = MainWindow.get_current_glyph (); 59 BackgroundImage? bg = g.get_background_image (); 60 BackgroundImage background; 61 62 if (bg == null) { 63 return; 64 } 65 66 background = (!) bg; 67 68 g.store_undo_state (); 69 70 background.handler_press (x, y); 71 72 begin_x = x; 73 begin_y = y; 74 75 img_offset_x = background.img_offset_x; 76 img_offset_y = background.img_offset_y; 77 78 img_scale_x = background.img_scale_x; 79 80 img_width = background.get_img ().get_width () * background.img_scale_x; 81 img_height = background.get_img ().get_height () * background.img_scale_y; 82 83 background.start_rotation_preview (); 84 85 move_bg = true; 86 87 last_x = x; 88 last_y = y; 89 }); 90 91 release_action.connect((self, b, x, y) => { 92 Glyph g = MainWindow.get_current_glyph (); 93 BackgroundImage? bg = g.get_background_image (); 94 double coordinate_x, coordinate_y; 95 96 if (bg == null) { 97 return; 98 } 99 100 BackgroundImage background = (!) bg; 101 102 coordinate_x = Glyph.path_coordinate_x (x); 103 coordinate_y = Glyph.path_coordinate_y (y); 104 105 if (background.selected_handle == 2) { 106 background.set_img_rotation_from_coordinate (coordinate_x, coordinate_y); 107 } 108 109 img_offset_x = background.img_offset_x; 110 img_offset_y = background.img_offset_y; 111 112 background.handler_release (x, y); 113 114 move_bg = false; 115 }); 116 117 move_action.connect((self, x, y) => { 118 move (x, y); 119 }); 120 121 key_press_action.connect ((self, keyval) => { 122 move_bg = true; 123 begin_x = 0; 124 begin_y = 0; 125 126 switch (keyval) { 127 case Key.UP: 128 move (0, -1); 129 break; 130 case Key.DOWN: 131 move (0, 1); 132 break; 133 case Key.LEFT: 134 move (-1, 0); 135 break; 136 case Key.RIGHT: 137 move (1, 0); 138 break; 139 default: 140 break; 141 } 142 143 move_bg = false; 144 }); 145 146 147 draw_action.connect ((self, cairo_context, glyph) => { 148 Glyph g = MainWindow.get_current_glyph (); 149 BackgroundImage? background_image = g.get_background_image (); 150 if (background_image == null) return; 151 152 ((!) background_image).draw_handle (cairo_context, glyph); 153 }); 154 } 155 156 void move (int x, int y) { 157 Glyph g = MainWindow.get_current_glyph (); 158 BackgroundImage? background_image = g.get_background_image (); 159 BackgroundImage bg = (!) background_image; 160 double xscale, yscale, dx, dy, xc, yc; 161 double coordinate_x, coordinate_y; 162 double view_zoom; 163 164 if (background_image == null) { 165 return; 166 } 167 168 bg.handler_move (x, y); 169 170 dx = x - begin_x; 171 dy = y - begin_y; 172 173 dx *= 1 / g.view_zoom; 174 dy *= 1 / g.view_zoom; 175 176 dx *= PenTool.precision; 177 dy *= PenTool.precision; 178 179 if (bg.selected_handle == 2) { 180 coordinate_x = Glyph.path_coordinate_x (x); 181 coordinate_y = Glyph.path_coordinate_y (y); 182 view_zoom = MainWindow.get_current_glyph ().view_zoom; 183 bg.preview_img_rotation_from_coordinate (coordinate_x, coordinate_y, view_zoom); 184 } 185 186 if (bg.selected_handle == 1) { 187 xscale = img_scale_x * ((img_width - dx) / img_width); 188 yscale = xscale; 189 190 xc = bg.img_middle_x; 191 yc = bg.img_middle_y; 192 193 bg.set_img_scale (xscale, yscale); 194 195 bg.img_middle_x = xc; 196 bg.img_middle_y = yc; 197 } 198 199 if (move_bg && bg.selected_handle <= 0) { 200 bg.set_img_offset (this.img_offset_x + dx, this.img_offset_y + dy); 201 } 202 203 GlyphCanvas.redraw (); 204 205 last_x = x; 206 last_y = y; 207 } 208 209 public static void load_background_image () { 210 // generate png file if needed and load the image with cairo 211 imported_surface = imported_background.get_img (); 212 213 IdleSource idle = new IdleSource (); 214 idle.set_callback (() => { 215 TabBar tb = MainWindow.get_tab_bar (); 216 Glyph g = MainWindow.get_current_glyph (); 217 218 g.set_background_image (imported_background); 219 imported_background.center_in_glyph (); 220 221 Toolbox.select_tool_by_name ("zoom_background_image"); 222 tb.select_tab_name (g.get_name ()); 223 Toolbox.select_tool_by_name ("cut_background"); 224 225 GlyphCanvas.redraw (); 226 return false; 227 }); 228 idle.attach (null); 229 } 230 231 internal static void import_background_image () { 232 FileChooser fc = new FileChooser (); 233 234 fc.file_selected.connect ((fn) => { 235 BackgroundImage bg; 236 string path; 237 238 if (fn != null) { 239 path = (!) fn; 240 bg = new BackgroundImage (path); 241 imported_background = bg; 242 MainWindow.native_window.load_background_image (); 243 } 244 }); 245 246 MainWindow.file_chooser (t_("Select background image"), fc, FileChooser.LOAD); 247 } 248 } 249 250 } 251