OverviewTools.vala
/*
Copyright (C) 2014 2015 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;
namespace BirdFont {
public enum Transform {
SLANT,
SIZE
}
public class OverviewTools : ToolCollection {
static LabelTool all_glyphs;
static LabelTool default_glyphs;
static LabelTool unicode;
static Gee.ArrayList<LabelTool> custom_character_sets;
public static Gee.ArrayList<Expander> expanders;
public ZoomBar zoom_bar;
public static Expander zoom_expander;
public static SpinButton skew;
public static SpinButton resize;
public static double current_master_size;
public OverviewTools () {
Expander font_name = new Expander ();
Expander character_sets = new Expander (t_("Character Sets"));
Expander zoom_expander = new Expander (t_("Zoom"));
Expander transform_slant_expander = new Expander (t_("Transform"));
Expander transform_size_expander = new Expander ();
Expander glyph_expander = new Expander (t_("Glyph"));
Expander multi_master = new Expander (t_("Multi-Master"));
expanders = new Gee.ArrayList<Expander> ();
custom_character_sets = new Gee.ArrayList<LabelTool> ();
font_name.add_tool (new FontName ());
zoom_bar = new ZoomBar ();
zoom_bar.new_zoom.connect ((z) => {
get_overview ().set_zoom (z);
});
zoom_expander.add_tool (zoom_bar);
all_glyphs = new LabelTool (t_("All Glyphs"));
all_glyphs.has_counter = true;
all_glyphs.select_action.connect ((self) => {
Overview overview = get_overview ();
overview.display_all_available_glyphs ();
update_overview_characterset (overview);
FontDisplay.dirty_scrollbar = true;
});
character_sets.add_tool (all_glyphs);
default_glyphs = new LabelTool (t_("Default"));
default_glyphs.has_counter = true;
default_glyphs.select_action.connect ((self) => {
Overview overview = get_overview ();
GlyphRange gr = new GlyphRange ();
DefaultCharacterSet.use_default_range (gr);
overview.set_current_glyph_range (gr);
update_overview_characterset (overview);
FontDisplay.dirty_scrollbar = true;
});
character_sets.add_tool (default_glyphs);
unicode = new LabelTool (t_("Unicode"));
unicode.has_counter = true;
unicode.select_action.connect ((self) => {
Overview overview = get_overview ();
GlyphRange gr = new GlyphRange ();
DefaultCharacterSet.use_full_unicode_range (gr);
overview.set_current_glyph_range (gr);
update_overview_characterset (overview);
FontDisplay.dirty_scrollbar = true;
});
character_sets.add_tool (unicode);
character_sets.set_persistent (true);
character_sets.set_unique (false);
skew = new SpinButton ("skew_overview", t_("Skew"));
skew.set_big_number (true);
skew.set_int_value ("0.000");
FontSettings settings = BirdFont.get_current_font ().settings;
string? skew_value = settings.get_setting ("skew_overview");
if (skew_value != null) {
skew.set_int_value ((!) skew_value);
}
skew.set_int_step (1);
skew.set_min (-100);
skew.set_max (100);
skew.show_icon (true);
skew.set_persistent (false);
transform_slant_expander.add_tool (skew);
Tool transform_slant = new Tool ("transform_slant", t_("Transform"));
transform_slant.set_icon ("transform");
transform_slant.select_action.connect ((self) => {
FontSettings fs = BirdFont.get_current_font ().settings;
fs.set_setting ("skew_overview", @"$(skew.get_value ())");
transform_slant.selected = false;
process_transform (Transform.SLANT);
BirdFont.get_current_font ().touch ();
});
transform_slant.selected = false;
transform_slant.set_persistent (false);
transform_slant_expander.add_tool (transform_slant);
resize = new SpinButton ("resize_overview", t_("Resize"));
resize.set_big_number (true);
resize.set_int_value ("100.0");
string? resize_value = settings.get_setting ("resize_overview");
if (resize_value != null) {
resize.set_int_value ((!) resize_value);
if (resize.get_value () <= 0) {
resize.set_int_value ("100.0");
}
}
resize.set_int_step (1);
resize.set_min (0);
resize.set_max (300);
resize.show_icon (true);
resize.set_persistent (false);
transform_size_expander.add_tool (resize);
Tool transform_size = new Tool ("transform_size", t_("Transform"));
transform_size.set_icon ("transform");
transform_size.select_action.connect ((self) => {
FontSettings fs = BirdFont.get_current_font ().settings;
fs.set_setting ("resize_overview", @"$(resize.get_value ())");
transform_size.selected = false;
process_transform (Transform.SIZE);
BirdFont.get_current_font ().touch ();
});
transform_size.selected = false;
transform_size.set_persistent (false);
transform_size_expander.add_tool (transform_size);
Tool alternate = new Tool ("alternate", t_("Create alternate"));
alternate.select_action.connect (add_new_alternate);
glyph_expander.add_tool (alternate);
Tool curve_orientation = new Tool ("curve_orientation", t_("Set curve orientation"));
curve_orientation.select_action.connect ((self) => {
Task t = new Task (fix_curve_orientation);
MainWindow.run_blocking_task (t);
IdleSource idle = new IdleSource ();
idle.set_callback (() => {
self.set_selected (false);
BirdFont.get_current_font ().touch ();
return false;
});
idle.attach (null);
});
glyph_expander.add_tool (curve_orientation);
Tool search_glyph = new Tool ("search", t_("Search"));
search_glyph.select_action.connect (search_for_glyph);
glyph_expander.add_tool (search_glyph);
SpinButton master_size;
current_master_size = 0;
master_size = new SpinButton ("master_size", t_("Master Size")); /// Master refers to a glyph master in a multi-master font.
master_size.set_big_number (false);
master_size.set_int_value ("0.000");
master_size.set_int_step (1);
master_size.set_min (-1);
master_size.set_max (1);
master_size.show_icon (true);
master_size.set_persistent (false);
master_size.new_value_action.connect ((self) => {
current_master_size = self.get_value ();
MainWindow.get_overview ().update_item_list ();
GlyphCanvas.redraw ();
});
multi_master.add_tool (master_size);
Tool create_new_master = new Tool ("new_master", t_("Create new master font")); /// Master is a master in a multi-master font.
create_new_master.select_action.connect (create_master);
multi_master.add_tool (create_new_master);
expanders.add (font_name);
expanders.add (zoom_expander);
expanders.add (character_sets);
expanders.add (transform_slant_expander);
expanders.add (transform_size_expander);
expanders.add (glyph_expander);
if (BirdFont.has_argument ("--test")) {
expanders.add (multi_master);
}
}
void create_master () {
Font font = BirdFont.get_current_font ();
int i = 0;
GlyphCollection glyph_collection;
GlyphCollection? gc = font.get_glyph_collection_index (i);
Glyph g;
while (gc != null) {
glyph_collection = (!) gc;
// FIXME: MASTER NAME
GlyphMaster master = new GlyphMaster.for_id("Master 2");
g = glyph_collection.get_interpolated (current_master_size);
master.add_glyph(g);
glyph_collection.add_master (master);
glyph_collection.set_selected_master (master);
i++;
gc = font.get_glyph_collection_index (i);
}
MainWindow.get_overview ().update_item_list ();
GlyphCanvas.redraw ();
}
void fix_curve_orientation () {
Overview o;
Glyph g;
Overview.OverviewUndoItem ui;
o = get_overview ();
ui = new Overview.OverviewUndoItem ();
Font f = BirdFont.get_current_font ();
ui.alternate_sets = f.alternates.copy ();
foreach (GlyphCollection gc in o.selected_items) {
if (gc.length () > 0) {
g = gc.get_current ();
ui.glyphs.add (gc.copy_deep ());
g.add_help_lines ();
g.fix_curve_orientation ();
}
}
o.undo_items.add (ui);
GlyphCanvas.redraw ();
}
public void search_for_glyph (Tool tool) {
tool.set_selected (false);
Overview.search ();
}
public void add_new_alternate (Tool tool) {
Overview o = MainWindow.get_overview ();
OverviewItem oi = o.selected_item;
GlyphCollection? gc;
tool.set_selected (false);
gc = (!) oi.glyphs;
if (oi.glyphs != null && ((!) oi.glyphs).is_unassigned ()) {
gc = null;
}
MainWindow.tabs.add_tab (new OtfFeatureTable (gc));
}
public void process_transform (Transform transform) {
Overview o;
Glyph g;
Overview.OverviewUndoItem ui;
o = get_overview ();
ui = new Overview.OverviewUndoItem ();
Font f = BirdFont.get_current_font ();
ui.alternate_sets = f.alternates.copy ();
foreach (GlyphCollection gc in o.selected_items) {
if (gc.length () > 0) {
g = gc.get_current ();
ui.glyphs.add (gc.copy_deep ());
g.add_help_lines ();
if (transform == Transform.SLANT) {
if (skew.get_value () != 0) {
DrawingTools.resize_tool.skew_glyph (g, -skew.get_value (), 0, false);
}
}
if (transform == Transform.SIZE) {
if (resize.get_value () != 100) {
double scale = resize.get_value () / 100;
DrawingTools.resize_tool.resize_glyph (g, scale, scale, false);
}
}
}
}
foreach (OverviewItem item in o.visible_items) {
item.clear_cache ();
item.draw_glyph_from_font ();
}
o.undo_items.add (ui);
MainWindow.get_overview ().update_item_list ();
GlyphCanvas.redraw ();
}
public Overview get_overview () {
FontDisplay fd = MainWindow.get_current_display ();
if (fd is Overview || fd is GlyphSelection) {
return (Overview) fd;
}
warning ("Current tab is not overview.");
return new Overview ();
}
public static void show_all_available_characters () {
all_glyphs.select_action (all_glyphs);
}
public static void update_overview_characterset (Overview? tab = null) {
GlyphRange gr;
uint size;
Overview overview;
// All characters
size = BirdFont.get_current_font ().length ();
all_glyphs.number = get_display_value (size);
// Default
gr = new GlyphRange ();
DefaultCharacterSet.use_default_range (gr);
size = gr.get_length ();
default_glyphs.number = get_display_value (size);
// Unicode
gr = new GlyphRange ();
DefaultCharacterSet.use_full_unicode_range (gr);
size = gr.get_length ();
unicode.number = get_display_value (size);
overview = (tab == null) ? MainWindow.get_overview () : (!) tab;
// set selected item
all_glyphs.set_selected (false);
default_glyphs.set_selected (false);
unicode.set_selected (false);
if (overview.all_available) {
all_glyphs.set_selected (true);
} else if (overview.glyph_range.name == "Default") {
default_glyphs.set_selected (true);
} else if (overview.glyph_range.name == "Unicode") {
unicode.set_selected (true);
}
Toolbox.redraw_tool_box ();
}
static string get_display_value (uint size) {
double k;
string display_size;
if (size >= 1000) {
k = size / 1000.0;
size = (uint) Math.rint (k);
display_size = @"$(size)k";
} else {
display_size = @"$(size)";
}
return display_size;
}
public override Gee.ArrayList<Expander> get_expanders () {
return expanders;
}
public override Gee.ArrayList<string> get_displays () {
Gee.ArrayList<string> d = new Gee.ArrayList<string> ();
d.add ("Overview");
return d;
}
}
}