.
1 /*
2 Copyright (C) 2015 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 LayerLabel : Tool {
20
21 public bool selected_layer { get; set; }
22 public string label { get; set; }
23
24 public Layer layer;
25 Text label_text;
26
27 /** Add margin when layer is moves. */
28 bool active_layer = false;
29
30 public LayerLabel (Layer layer) {
31 base ();
32
33 this.layer = layer;
34 this.label = layer.name;
35
36 selected_layer = false;
37
38 set_text ();
39
40 panel_press_action.connect ((selected, button, tx, ty) => {
41 if (y <= ty <= y + h) {
42 if (tx >= w - 30 * Toolbox.get_scale ()) {
43 DrawingTools.deselect_layers ();
44 remove_layer ();
45 } if (tx < 25 * Toolbox.get_scale ()) {
46 layer.visible = !layer.visible;
47 GlyphCanvas.redraw ();
48 BirdFont.get_current_font ().touch ();
49 MainWindow.get_current_glyph ().clear_active_paths ();
50 } else {
51 active_layer = true;
52 select_layer ();
53 }
54 } else {
55 selected_layer = false;
56 }
57 });
58
59 panel_double_click_action.connect ((selected, button, tx, ty) => {
60 if (y <= ty <= y + h) {
61 if (25 * Toolbox.get_scale () <= tx <= w - 30 * Toolbox.get_scale ()) {
62 set_layer_name ();
63 }
64 }
65 });
66
67 panel_move_action.connect ((selected, button, tx, ty) => {
68 if (active_layer) {
69 if (ty > y) {
70 move_layer_down ();
71 } else if (ty < y - h) {
72 move_layer_up ();
73 }
74
75 MainWindow.get_toolbox ().update_expanders ();
76 redraw ();
77 }
78
79 return false;
80 });
81
82 panel_release_action.connect ((selected, button, tx, ty) => {
83 active_layer = false;
84 });
85 }
86
87 void move_layer_up () {
88 int i;
89 Glyph g = MainWindow.get_current_glyph ();
90
91 // g.layers is ordered from bottom to top
92 i = DrawingTools.layer_tools.tool.size - g.current_layer - 1;
93 g.move_layer_up ();
94
95 DrawingTools.update_layers ();
96
97 if (i < 0) {
98 i = 0;
99 }
100
101 set_moving_label (i);
102 }
103
104 void move_layer_down () {
105 int i;
106 Glyph g = MainWindow.get_current_glyph ();
107
108 i = DrawingTools.layer_tools.tool.size - g.current_layer + 1;
109 g.move_layer_down ();
110
111 DrawingTools.update_layers ();
112
113 if (i >= DrawingTools.layer_tools.tool.size) {
114 i = DrawingTools.layer_tools.tool.size - 1;
115 }
116
117 set_moving_label (i);
118 }
119
120 void set_moving_label (int i) {
121 LayerLabel label;
122 int j = 0;
123 foreach (Tool layer in DrawingTools.layer_tools.tool) {
124 label = (LayerLabel) layer;
125 if (i == j) {
126 label.active_layer = true;
127 }
128 j++;
129 }
130 }
131
132 void set_text () {
133 double text_height;
134
135 label_text = new Text ();
136 label_text.set_text (label);
137 text_height = 17 * Toolbox.get_scale ();
138 label_text.set_font_size (text_height);
139 }
140
141 void set_layer_name () {
142 TextListener listener;
143
144 listener = new TextListener (t_("Layer"), layer.name, t_("Set"));
145
146 listener.signal_text_input.connect ((text) => {
147 layer.name = text;
148 label = text;
149 set_text ();
150 redraw ();
151 });
152
153 listener.signal_submit.connect (() => {
154 TabContent.hide_text_input ();
155 });
156
157 TabContent.show_text_input (listener);
158 }
159
160 public void select_layer () {
161 Glyph glyph = MainWindow.get_current_glyph ();
162 glyph.set_current_layer (layer);
163 DrawingTools.deselect_layers ();
164 selected_layer = true;
165 MainWindow.get_current_glyph ().clear_active_paths ();
166 GlyphCanvas.redraw ();
167
168 Font font = BirdFont.get_current_font ();
169 int index = glyph.get_layer_index (layer);
170 font.settings.set_setting (@"Active Layer $(glyph.get_name ())", @"$(index)");
171 }
172
173 public void remove_layer () {
174 // remove layer after the click loop
175 IdleSource idle = new IdleSource ();
176
177 idle.set_callback (() => {
178 Glyph g = MainWindow.get_current_glyph ();
179 g.store_undo_state ();
180 g.layers.remove_layer (layer);
181 DrawingTools.update_layers ();
182 BirdFont.get_current_font ().touch ();
183 g.clear_active_paths ();
184 GlyphCanvas.redraw ();
185 return false;
186 });
187
188 idle.attach (null);
189 }
190
191 public override void draw_tool (Context cr, double px, double py) {
192 Text visibility_icon;
193 double x = this.x - px;
194 double y = this.y - py;
195 double text_width;
196 double visibility_center_y;
197 string visibility;
198
199 // background
200 if (selected_layer) {
201 cr.save ();
202 Theme.color (cr, "Menu Background");
203 // labels overlap with 2 pixels
204 cr.rectangle (0, y - 2 * Toolbox.get_scale (), w, h);
205 cr.fill ();
206 cr.restore ();
207 }
208
209 // tab label
210 cr.save ();
211
212 text_width = Toolbox.allocation_width;
213 text_width -= 30 * Toolbox.get_scale (); // delete button
214 text_width -= 20 * Toolbox.get_scale (); // visibility
215
216 label_text.truncate (text_width);
217 Theme.text_color (label_text, "Text Tool Box");
218 label_text.draw_at_top (cr, x + 20 * Toolbox.get_scale (), y);
219
220 visibility = layer.visible ? "layer_visible" : "layer_hidden";
221 visibility_icon = new Text (visibility, 30 * Toolbox.get_scale ());
222 visibility_icon.load_font ("icons.bf");
223 Theme.text_color (visibility_icon, "Text Tool Box");
224 visibility_center_y = y + h / 2.0;
225 visibility_center_y -= visibility_icon.get_height () / 2.0;
226 visibility_center_y -= 2;
227 visibility_icon.draw_at_top (cr, x, visibility_center_y);
228
229 cr.restore ();
230
231 cr.save ();
232 Theme.color (cr, "Text Tool Box");
233 cr.set_line_width (1);
234 cr.move_to (w - 20, y + h / 2 - 2.5 - 2);
235 cr.line_to (w - 25, y + h / 2 + 2.5 - 2);
236 cr.move_to (w - 20, y + h / 2 + 2.5 - 2);
237 cr.line_to (w - 25, y + h / 2 - 2.5 - 2);
238 cr.stroke ();
239 cr.restore ();
240 }
241 }
242
243 }
244