Commit 674f9ea
new overview
Changed files (7)
modifiedlibbirdfont/BirdFontFile.valamodifiedlibbirdfont/DropMenu.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/Line.valamodifiedlibbirdfont/OverView.valaaddedlibbirdfont/OverViewItem.vala
Diff
@@ -643,12 +643,29 @@ class BirdFontFile { private void parse_font_boundries (Xml.Node* node) { for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {- if (iter->name == "top_limit") font.top_limit = parse_double_from_node (iter);- if (iter->name == "top_position") font.top_position = parse_double_from_node (iter);- if (iter->name == "x-height") font.xheight_position = parse_double_from_node (iter);- if (iter->name == "base_line") font.base_line = parse_double_from_node (iter);- if (iter->name == "bottom_position") font.bottom_position = parse_double_from_node (iter);- if (iter->name == "bottom_limit") font.bottom_limit = parse_double_from_node (iter);+ if (iter->name == "top_limit" && "" == iter->children->content) {+ font.top_limit = parse_double_from_node (iter);+ }+ + if (iter->name == "top_position" && "" == iter->children->content) {+ font.top_position = parse_double_from_node (iter);+ }+ + if (iter->name == "x-height" && "" == iter->children->content) {+ font.xheight_position = parse_double_from_node (iter);+ }+ + if (iter->name == "base_line" && "" == iter->children->content) {+ font.base_line = parse_double_from_node (iter);+ }+ + if (iter->name == "bottom_position" && "" == iter->children->content) {+ font.bottom_position = parse_double_from_node (iter);+ }+ + if (iter->name == "bottom_limit" && "" == iter->children->content) {+ font.bottom_limit = parse_double_from_node (iter);+ } } } @@ -662,7 +679,7 @@ class BirdFontFile { else warning (@"Failed to parse double for \"$(iter->content)\"\n"); } - return (r) ? d : 0;+ return (r) ? d : 0.0; } /** Parse the new glyph format */@@ -188,7 +188,7 @@ public class DropMenu : GLib.Object { if (direction == MenuDirection.DROP_DOWN) { cr.rectangle (x - 100 + 18, y + 18, 88, actions.length () * item_height - 12); } else {- cr.rectangle (x - 100 + 18, y + 6 - actions.length () * item_height, 88, actions.length () * item_height - 12);+ cr.rectangle (x - 100 + 19, y + 6 - actions.length () * item_height, 88, actions.length () * item_height - 12); } cr.fill_preserve ();@@ -201,7 +201,7 @@ public class DropMenu : GLib.Object { cr.set_source_rgba (122/255.0, 150/255.0, 169/255.0, 1); cr.set_line_width (0); - cr.rectangle (x, y - 7, 12, 7);+ cr.rectangle (x, y - 7, 13, 7); cr.fill_preserve (); cr.stroke ();@@ -218,7 +218,7 @@ public class DropMenu : GLib.Object { else iy = y - 8 - n * item_height; - ix = x - 100 + 20;+ ix = x - 100 + 21; item.draw (ix, iy, cr); n++;@@ -82,12 +82,12 @@ public class Font : GLib.Object { public Font () { // positions in pixels at first zoom level // default x-height should be 60 in 1:1- top_limit = -66 ;- top_position = -54;- xheight_position = -38;- base_line = 18;- bottom_position = 38;- bottom_limit = 45;+ top_limit = -84 ;+ top_position = -72;+ xheight_position = -56;+ base_line = 0;+ bottom_position = 20;+ bottom_limit = 27; } public void touch () {@@ -534,11 +534,18 @@ public class Glyph : FontDisplay { } private void help_line_event (double x, double y) {- double mx = x;- double my = y;+ bool m = false;+ + foreach (Line line in vertical_help_lines) {+ if (!m && line.event_move_to (x, y, allocation)) {+ m = true;+ }+ } - foreach (Line line in get_all_help_lines ()) {- line.event_move_to (mx, my, x, y, allocation);+ foreach (Line line in horizontal_help_lines) {+ if (!m && line.event_move_to (x, y, allocation)) {+ m = true;+ } } } @@ -572,8 +579,8 @@ public class Glyph : FontDisplay { return; } - help_line_event (x, y); -+ help_line_event (x, y);+ t.move_action (t, (int) x, (int) y); if (BirdFont.show_coordinates) {@@ -601,7 +608,9 @@ public class Glyph : FontDisplay { } private unowned List<Line> get_all_help_lines () {- while (all_lines.length () > 0) all_lines.delete_link (all_lines.first ());+ while (all_lines.length () > 0) {+ all_lines.delete_link (all_lines.first ());+ } all_lines.concat (vertical_help_lines.copy ()); all_lines.concat (horizontal_help_lines.copy ());@@ -624,15 +633,26 @@ public class Glyph : FontDisplay { } public override void button_press (uint button, double ex, double ey) { + bool moving_lines = false; pointer_begin_x = ex; pointer_begin_y = ey; - foreach (Line line in get_all_help_lines ()) {- if (line.button_press ()) {- return;+ foreach (Line line in horizontal_help_lines) {+ if (!moving_lines && line.is_visible () && line.button_press ()) {+ moving_lines = true;+ }+ }++ foreach (Line line in vertical_help_lines) {+ if (!moving_lines && line.is_visible () && line.button_press ()) {+ moving_lines = true; } } + if (moving_lines) {+ return;+ }+ if (KeyBindings.has_ctrl ()) { move_view = true; move_offset_x = view_offset_x;@@ -69,7 +69,10 @@ public class Line : GLib.Object { public void set_visible (bool v) { visible = v; }- ++ public bool is_visible () {+ return visible;+ } public void set_moveable (bool m) { moveable = m;@@ -99,11 +102,12 @@ public class Line : GLib.Object { g = MainWindow.get_current_glyph (); g.store_undo_state ();- - return true;+ } else {+ move = false;+ active = false; } - return false;+ return move; } void redraw_line () {@@ -121,60 +125,28 @@ public class Line : GLib.Object { public void move_line_to (double x, double y, Allocation allocation) { set_move (true);- event_move_to (x, y, x, y, allocation);+ event_move_to (x, y, allocation); } - public void event_move_to (double x, double y, double ax, double ay, Allocation allocation) {+ public bool event_move_to (double x, double y, Allocation allocation) { double p, c; bool a = false; Glyph g = MainWindow.get_current_glyph (); double ivz = 1/g.view_zoom; double margin = 10;-- if (!moveable) return;-- if (move) {- double np = pos;+ double none = 0;+ double tpy; - redraw_line (); // clear old position- - if (is_vertical ()) {- pos = Glyph.path_coordinate_x (x);-- if (GridTool.is_visible ()) {- GridTool.tie_coordinate (ref pos, ref ay);- }- - redraw_line (); // draw at new position- } else {- // FIXME: flip back the y axis for lines- if (GridTool.is_visible ()) {- double tpy = Glyph.path_coordinate_y (y);- GridTool.tie_coordinate (ref ax, ref tpy);- pos = -tpy;- } else {- pos = -Glyph.path_coordinate_y (y);- }- redraw_line ();- }-- if (Math.fabs (np - pos) > 10) {- queue_draw_area (0, 0, g.allocation.width, g.allocation.height);- }-- position_updated (pos); // signal update-- BirdFont.get_current_font ().touch ();- - swap_lines ();+ if (!moveable) {+ return false; } - if (is_vertical ()) { // over line handle y- if (ay > g.allocation.height - 10) {+ if (is_vertical ()) { // over line handle (y)+ if (y > g.allocation.height - 10) { p = get_coordinate (); - c = ax * ivz + g.view_offset_x;+ c = x * ivz + g.view_offset_x; a = (p - margin * ivz <= c <= p + margin * ivz); } @@ -184,10 +156,10 @@ public class Line : GLib.Object { set_active (a); - } else { // over line handle x- if (ax > g.allocation.width - 10) {+ } else { // over line handle (x+ if (x > g.allocation.width - 10) { p = get_coordinate ();- c = ay * ivz + g.view_offset_y;+ c = y * ivz + g.view_offset_y; a = (p - margin * ivz <= c <= p + margin * ivz); } @@ -197,52 +169,49 @@ public class Line : GLib.Object { set_active (a); }- }- - private void swap_lines () {- double ivz = 1 / MainWindow.get_current_glyph ().view_zoom;- - if (!moveable) return;- - // switch to correct line if this line passes the next one in the sorted list- if (list_item != null) {- unowned List<Line> ll = (!) list_item;++ // move the line+ if (move) {+ double np = pos;+ redraw_line (); // clear old position - if (ll != ll.first ()) {- if (ll.prev.data.pos > pos) {- ll.prev.data.set_move (true);- ll.prev.data.set_visible (true);- set_move (false);- pos = ll.prev.data.pos;- ll.prev.data.pos += 1 * ivz;- - ll.data.position_updated (ll.data.pos);- ll.prev.data.position_updated (ll.prev.data.pos);+ if (is_vertical ()) {+ pos = Glyph.path_coordinate_x (x);++ if (GridTool.is_visible ()) {+ GridTool.tie_coordinate (ref pos, ref none); }+ + redraw_line (); // draw at new position+ } else {+ // FIXME: flip the y axis for lines+ if (GridTool.is_visible ()) {+ tpy = Glyph.path_coordinate_y (y);+ GridTool.tie_coordinate (ref none, ref tpy);+ pos = -tpy;+ } else {+ pos = -Glyph.path_coordinate_y (y);+ }+ redraw_line (); }- - if (ll != ll.last ()) {- if (ll.next.data.pos < pos) {- ll.next.data.set_move (true);- ll.next.data.set_visible (true);- pos = ll.next.data.pos;- ll.next.data.pos -= 1 * ivz;- set_move (false); - ll.data.position_updated (ll.data.pos);- ll.prev.data.position_updated (ll.prev.data.pos);- }+ if (Math.fabs (np - pos) > 10) {+ queue_draw_area (0, 0, g.allocation.width, g.allocation.height); }- ++ position_updated (pos); // signal update++ BirdFont.get_current_font ().touch (); }- ++ return move; } public bool get_active () { return active; } - protected void set_active (bool active) {+ public void set_active (bool active) { this.active = active; } @@ -18,35 +18,25 @@ namespace BirdFont { /** A display with all glyphs present in this font. */ public class OverView : FontDisplay {- Allocation allocation;+ public Allocation allocation; + int selected = 0;+ int first_visible = 0; int rows = 0; int items_per_row = 0;- uint32 first_character = 0;- int64 first_visible = 0;- uint32 selected = 0; double view_offset_y = 0; double view_offset_x = 0; - int nail_height = 0;- int nail_width = 0;-- double nail_zoom_height = 0;- double nail_zoom_width = 0;+ public signal void open_new_glyph_signal (unichar c);+ public signal void open_glyph_signal (GlyphCollection c); - public signal void open_glyph_signal (string c);- GlyphRange glyph_range;-- List<GlyphCollection> visible_characters = new List<GlyphCollection> ();-- List<unichar> zoom_list = new List<unichar> ();- int zoom_list_index = 0;+ + List<OverViewItem> visible_items = new List<OverViewItem> (); List<GlyphCollection> deleted_glyphs = new List<GlyphCollection> ();- List<CharacterInfo> unicode_database_info = new List<CharacterInfo> ();- + bool all_available = true; /** Show unicode database info. */@@ -62,42 +52,63 @@ public class OverView : FontDisplay { reset_zoom (); - this.open_glyph_signal.connect ((t, s) => {+ this.open_glyph_signal.connect ((glyph_collection) => { TabBar tabs = MainWindow.get_tab_bar ();- Toolbox tools = MainWindow.get_toolbox ();- bool selected = tabs.select_char (s);- unichar new_char = s.get_char (0);- Font f = BirdFont.get_current_font ();- + string n = glyph_collection.get_current ().name;+ bool selected = tabs.select_char (n);+ GlyphCanvas canvas;+ Glyph g = glyph_collection.get_current (); + if (!selected) {- GlyphCollection? fg;- Glyph g;+ canvas = MainWindow.get_glyph_canvas ();+ tabs.add_tab (g);+ canvas.set_current_glyph (g);+ set_initial_zoom ();+ g.close_path ();+ }+ });++ this.open_new_glyph_signal.connect ((character) => {+ StringBuilder name = new StringBuilder ();+ TabBar tabs = MainWindow.get_tab_bar ();+ Font font = BirdFont.get_current_font ();+ bool selected;+ GlyphCollection? fg;+ Glyph glyph;+ GlyphCanvas canvas; + name.append_unichar (character);+ selected = tabs.select_char (name.str);+ + if (!selected) { if (all_available) {- fg = f.get_glyph_collection_by_name (s);+ fg = font.get_glyph_collection_by_name (name.str); } else {- fg = f.get_glyph_collection (s);+ fg = font.get_glyph_collection (name.str); } - g = (fg == null) ? new Glyph (s, new_char) : ((!) fg).get_current ();- ZoomTool z = (ZoomTool) tools.get_tool ("zoom_tool");+ glyph = (fg == null) ? new Glyph (name.str, character) : ((!) fg).get_current ();+ font.add_glyph (glyph);+ tabs.add_tab (glyph); - stdout.printf (@"Open '%s' %u (%s)\n", s, new_char, Font.to_hex (new_char));+ canvas = MainWindow.get_glyph_canvas ();+ canvas.set_current_glyph (glyph); - z.store_current_view ();- f.add_glyph (g);- tabs.add_tab (g);- - MainWindow.get_glyph_canvas ().set_current_glyph (g);- - g.close_path ();- g.default_zoom ();- z.store_current_view ();+ glyph.close_path ();+ set_initial_zoom (); } }); update_scrollbar (); }+ + private void set_initial_zoom () {+ Toolbox tools = MainWindow.get_toolbox ();+ ZoomTool z = (ZoomTool) tools.get_tool ("zoom_tool");+ z.store_current_view ();+ MainWindow.get_current_glyph ().default_zoom ();+ z.store_current_view ();+ } public double get_height () { double l;@@ -114,7 +125,7 @@ public class OverView : FontDisplay { l = glyph_range.length (); } - return 2.0 * nail_height * (l / rows);+ return 2.0 * OverViewItem.height * (l / rows); } public bool selected_char_is_visible () {@@ -127,13 +138,11 @@ public class OverView : FontDisplay { public override void scroll_wheel_up (double x, double y) { key_up ();- close_menus (); redraw_area (0, 0, allocation.width, allocation.height); } public override void scroll_wheel_down (double x, double y) { key_down ();- close_menus (); redraw_area (0, 0, allocation.width, allocation.height); } @@ -143,83 +152,39 @@ public class OverView : FontDisplay { } public override void zoom_min () {- int minw = 26 * 2;- int minh = 46 * 2;- - if (zoom_value_in_range (minw, minh)) {- nail_width = minw;- nail_height = minh;- - nail_zoom_height = minw; - nail_zoom_width = minh; + OverViewItem.width = OverViewItem.DEFAULT_WIDTH * 0.5;+ OverViewItem.height = OverViewItem.DEFAULT_HEIGHT * 0.5;+ OverViewItem.margin = OverViewItem.DEFAULT_MARGIN * 0.5; - adjust_scroll ();- redraw_area (0, 0, allocation.width, allocation.height);- } else {- warn_if_reached ();- } + redraw_area (0, 0, allocation.width, allocation.height); } public override void reset_zoom () {- nail_height = 210;- nail_width = 150;- - nail_zoom_height = nail_height; - nail_zoom_width = nail_width;+ OverViewItem.width = OverViewItem.DEFAULT_WIDTH;+ OverViewItem.height = OverViewItem.DEFAULT_HEIGHT;+ OverViewItem.margin = OverViewItem.DEFAULT_MARGIN; - adjust_scroll (); redraw_area (0, 0, allocation.width, allocation.height); } public override void zoom_max () {- if (zoom_value_in_range (allocation.width, allocation.height)) {- nail_width = allocation.width;- nail_height = allocation.height;- - nail_zoom_height = allocation.height; - nail_zoom_width = allocation.width; - - adjust_scroll ();- redraw_area (0, 0, allocation.width, allocation.height);- } else {- warn_if_reached ();- }+ OverViewItem.width = allocation.width;+ OverViewItem.height = allocation.height;+ redraw_area (0, 0, allocation.width, allocation.height); } public override void zoom_in () {- double w = (1.1 * nail_width);- double h = (1.1 * nail_height);- int nw = (int) w;- int nh = (int) h;- - if (zoom_value_in_range (nw, nh)) {- nail_width = nw;- nail_height = nh;- - nail_zoom_height = h; - nail_zoom_width = w;- - adjust_scroll ();- redraw_area (0, 0, allocation.width, allocation.height);- }+ OverViewItem.width *= 1.1;+ OverViewItem.height *= 1.1;+ OverViewItem.margin *= 1.1; + redraw_area (0, 0, allocation.width, allocation.height); } public override void zoom_out () {- double w = (nail_width / 1.1);- double h = (nail_height / 1.1);- int nw = (int) w;- int nh = (int) h;- - if (zoom_value_in_range (nw, nh)) {- nail_width = nw;- nail_height = nh;-- nail_zoom_height = h; - nail_zoom_width = w;- - adjust_scroll (); - redraw_area (0, 0, allocation.width, allocation.height);- }+ OverViewItem.width *= 0.9;+ OverViewItem.height *= 0.9;+ OverViewItem.margin *= 0.9; + redraw_area (0, 0, allocation.width, allocation.height); } private bool zoom_value_in_range (int w, int h) {@@ -227,33 +192,12 @@ public class OverView : FontDisplay { } public override void store_current_view () {- if (zoom_list_index + 1 < zoom_list.length ()) {- unowned List<unichar> n = zoom_list.nth (zoom_list_index);- while (n != zoom_list.last ()) zoom_list.delete_link (zoom_list.last ());- }- - zoom_list.append (selected);- zoom_list_index = (int) zoom_list.length () - 1;- - if (zoom_list.length () > 50) zoom_list.delete_link (zoom_list.first ()); } - public override void restore_last_view () - requires (zoom_list.length () > 0)- { - if (zoom_list_index - 1 < 0 || zoom_list.length () == 0)- return;- - zoom_list_index--;+ public override void restore_last_view () { } - public override void next_view () - requires (zoom_list.length () > 0)- {- if (zoom_list_index + 1 >= zoom_list.length ())- return;- - zoom_list_index++;+ public override void next_view () { } public override string get_name () {@@ -262,330 +206,85 @@ public class OverView : FontDisplay { public void display_all_available_glyphs () { all_available = true;- - first_character = 0;+ first_visible = 0; selected = 0; } - private unowned List<GlyphCollection> get_visible_glyphs () {- return visible_characters;- }- - public void draw_caption (int row, double width, Context cr, double y, uint64 index_begin) {+ void update_item_list () { string character_string;- double left_margin, x, caption_y; // for glyph caption- uint64 index = index_begin;- int i = row * items_per_row; Font f = BirdFont.get_current_font ();+ GlyphCollection? glyphs = null;+ uint32 index;+ OverViewItem item;+ double x, y;+ unichar character;+ Glyph glyph; - cr.save ();- cr.set_line_width (1);+ items_per_row = (int) Math.floor (allocation.width / OverViewItem.full_width ());+ rows = (int) Math.floor (allocation.height / OverViewItem.full_height ()); - x = 0;+ while (visible_items.length () > 0) {+ visible_items.remove_link (visible_items.first ());+ } - cr.set_font_size (14);-- left_margin = 0;- - for (int j = 0; j < items_per_row; j++) {- + visible_items = new List<OverViewItem> ();+ + index = (uint32) first_visible;+ x = OverViewItem.margin;+ y = OverViewItem.margin;+ for (int i = 0; i < items_per_row * rows; i++) { if (all_available) { if (! (0 <= index < f.length ())) { break; } - character_string = ((!) f.get_glyph_indice ((uint32) index)).get_name ();+ glyphs = f.get_glyph_collection_indice ((uint32) index);+ return_if_fail (glyphs != null);+ + glyph = ((!) glyphs).get_current ();+ character_string = glyph.name;+ character = glyph.unichar_code; } else { if (!(0 <= index < glyph_range.get_length ())) { break; } character_string = glyph_range.get_char ((uint32) index);+ glyphs = f.get_glyph_collection_by_name (character_string);+ character = character_string.get_char (0); } - cr.save ();- draw_thumbnail (cr, character_string, x, y);- cr.restore ();-- cr.save ();- - if (index == selected) {- cr.set_source_rgba (142/255.0, 158/255.0, 190/255.0, 1);- } else {- cr.set_source_rgba (164/255.0, 185/255.0, 215/255.0, 1);- }- - cr.set_line_join (LineJoin.ROUND);- cr.set_line_width(12);- - cr.rectangle (x, y + nail_height - 20, nail_width - 20, 10); - cr.stroke ();- cr.restore ();- - draw_menu (cr, character_string, x, y);+ item = new OverViewItem (glyphs, character, x, y);+ x += OverViewItem.full_width (); - draw_character_info_icon (cr, character_string, x, y);- - caption_y = y + 10 + nail_height - 20;- - cr.move_to (x, caption_y);+ if (x + OverViewItem.full_width () >= allocation.width) {+ x = OverViewItem.margin;+ y += OverViewItem.full_height ();+ } - cr.set_source_rgba (80/255.0, 95/255.0, 137/255.0, 0.5);- cr.show_text (character_string);+ item.selected = (i == selected); - x += nail_width;+ visible_items.append (item); index++;- i++; }- - cr.stroke(); } - private void draw_character_info_icon (Context cr, string character_string, double x, double y) {- double px = x + nail_width - 40;- double py = y + nail_height - 21;- CharacterInfo info;- unichar c = character_string.get_char ();- - if (character_string.char_count () > 1) {- warning ("Ligature - not a character");- c = '\0';- }- - info = new CharacterInfo (c);- unicode_database_info.append (info);- info.set_position (px, py);- info.draw_icon (cr);- }- - private void draw_menu (Context cr, string name, double x, double y) {- Font font = BirdFont.get_current_font ();- GlyphCollection? gl = font.get_glyph_collection (name);- GlyphCollection g;- DropMenu menu;- - if (gl == null) {- return;- }- - g = (!) gl;- - menu = g.get_version_list ();- menu.set_position (x + nail_width - 55, y + nail_height - 21);- menu.draw_icon (cr);- menu.draw_menu (cr);- - visible_characters.append (g);- }- - private bool draw_thumbnail (Context cr, string caption, double x, double y) {- Glyph? gl;- Glyph g;- Font f = BirdFont.get_current_font ();- - double gx, gy;- double x1, x2, y1, y2;- double scale = nail_zoom_width / 150.0;- double w, h;-- if (all_available) {- gl = f.get_glyph_by_name (caption);- } else {- gl = f.get_glyph (caption);- }-- w = nail_width - 19;- h = nail_height - 22;- - scale = nail_zoom_height / (210.0 - 15.0);- - if (gl == null) {- return false;- }- - g = (!) gl;- g.boundries (out x1, out y1, out x2, out y2);-- gx = 0;- gy = h / scale - 40;- - Surface s = new Surface.similar (cr.get_target (), Content.COLOR_ALPHA, (int) w, (int) h);- Context c = new Context (s);- - c.scale (scale, scale); - Svg.draw_svg_path (c, g.get_svg_data (), gx, gy);- - cr.save ();- cr.set_source_surface (s, x - 6, y);- cr.paint ();- cr.restore ();-- return true;- }-- // 150 * 190 px public override void draw (Allocation allocation, Context cr) {- double width;- double y;- uint64 t;- int i;- int n_items;- Font font = BirdFont.get_current_font ();- - while (unicode_database_info.length () > 0) {- unicode_database_info.remove_link (unicode_database_info.first ());- }- - while (visible_characters.length () > 9) {- visible_characters.remove_link (visible_characters.first ());- }- this.allocation = allocation; - cr.save ();- cr.set_source_rgba (1, 1, 1, 1);- cr.rectangle (0, 0, allocation.width, allocation.height + nail_height);- cr.fill ();- cr.restore ();-- if (all_available && font.length () == 0) {- draw_empty_canvas (allocation, cr);- }+ update_item_list (); - n_items = allocation.width / nail_width;- rows = allocation.height / nail_height;-- if (items_per_row != n_items) { - if (items_per_row == 0) {- items_per_row = n_items;- first_visible = first_character;- - key_down ();- key_up ();- } else {- items_per_row = n_items;- first_visible = first_character;- }- }-- width = (nail_width - 5) * items_per_row;- view_offset_x = (allocation.width - width) / 2.0;- - cr.translate (view_offset_x, view_offset_y);- - y = 0;- t = first_visible;- i = 0;- for (int j = 0; j < rows + 1; j++) {- draw_caption (i, width, cr, y, t);-- t += items_per_row;- y += nail_height;- i++;+ // FIXME: cr.translate (view_offset_x, view_offset_y);+ foreach (OverViewItem i in visible_items) {+ i.draw (cr); } - cr.restore (); // restore translation- - if (character_info != null) {- draw_character_info (allocation, cr, (!) character_info);+ if (visible_items.length () == 0) {+ draw_empty_canvas (allocation, cr); } }-- /** Display one entry from the Unicode Character Database. */- void draw_character_info (Allocation allocation, Context cr, CharacterInfo info) {- double x, y, w, h;- int i;- string unicode_value, unicode_description;- string[] column;- string entry;- int len = 0;- int length = 0;- bool see_also = false; - entry = info.get_entry ();- - foreach (string line in entry.split ("\n")) {- len = line.char_count ();- if (len > length) {- length = len;- }- }- - x = allocation.width * 0.1 - view_offset_x;- y = allocation.height * 0.1 - view_offset_y;- w = allocation.width * 0.9 - x - view_offset_x; - h = allocation.height * 0.9 - y - view_offset_y;- - if (w < 8 * length) {- w = 8 * length;- if (w > allocation.width - view_offset_x) {- x = -view_offset_x;- } else {- x = (allocation.width - view_offset_x- w) / 2.0;- }- }- - // background - cr.save ();- cr.set_source_rgba (1, 1, 1, 0.8);- cr.rectangle (x, y, w, h);- cr.fill ();- cr.restore ();-- cr.save ();- cr.set_source_rgba (0, 0, 0, 0.8);- cr.set_line_width (2);- cr.rectangle (x, y, w, h);- cr.stroke ();- cr.restore ();-- // database entry- i = 0;- foreach (string line in entry.split ("\n")) {- if (i == 0) {- column = line.split ("\t");- return_if_fail (column.length == 2);- unicode_value = "U+" + column[0];- unicode_description = column[1];-- draw_line (unicode_description, cr, x, y, i);- i++;-- draw_line (unicode_value, cr, x, y, i);- i++; - } else {- - if (line.has_prefix ("\t*")) {- draw_line (line.replace ("\t*", "•"), cr, x, y, i);- i++; - } else if (line.has_prefix ("\tx (")) {- if (!see_also) {- i++;- draw_line (_("See also:"), cr, x, y, i);- i++;- see_also = true;- }- - draw_line (line.replace ("\tx (", "•").replace (")", ""), cr, x, y, i);- i++;- } else {-- i++;- }- }- }- }- - void draw_line (string line, Context cr, double x, double y, int row) {- cr.save ();- cr.set_font_size (12);- cr.set_source_rgba (0, 0, 0, 1);- cr.move_to (x + 10, y + 28 + row * 18 * 1.2);- cr.show_text (line);- cr.restore (); - }- void draw_empty_canvas (Allocation allocation, Context cr) { cr.save (); cr.set_source_rgba (156/255.0, 156/255.0, 156/255.0, 1);@@ -594,17 +293,14 @@ public class OverView : FontDisplay { cr.show_text (_("No glyphs in this view.")); cr.restore (); }-- private void close_menus () {- } public void scroll_rows (int row_adjustment) { for (int i = 0; i < row_adjustment; i++) {- scroll (-nail_height);+ scroll (-OverViewItem.height); } for (int i = 0; i > row_adjustment; i--) {- scroll (nail_height);+ scroll (OverViewItem.height); } } @@ -652,14 +348,11 @@ public class OverView : FontDisplay { } default_position ();-- first_visible = r;- selected = (uint32) r; - adjust_scroll ();+ first_visible = (int) r; } - public override void scroll_to (double percent) {+ public override void scroll_to (double percent) requires (items_per_row > 0) { int64 r; double nrows; Font f;@@ -676,8 +369,7 @@ public class OverView : FontDisplay { redraw_area (0, 0, allocation.width, allocation.height); } - private void scroll (int64 pixel_adjustment) {-+ private void scroll (double pixel_adjustment) { if (first_visible < 0 && pixel_adjustment < 0) { scroll_top (); return;@@ -686,165 +378,95 @@ public class OverView : FontDisplay { view_offset_y += pixel_adjustment; if (view_offset_y >= 0) {- while (view_offset_y > nail_height) { - view_offset_y -= nail_height;+ while (view_offset_y > OverViewItem.height) { + view_offset_y -= OverViewItem.height; first_visible -= items_per_row; } first_visible -= items_per_row;- view_offset_y -= nail_height;- } else if (view_offset_y < -nail_height) {+ view_offset_y -= OverViewItem.height;+ } else if (view_offset_y < -OverViewItem.height) { view_offset_y = 0; first_visible += items_per_row; }- } public void scroll_top () {- first_visible = first_character;- view_offset_y = 0;- }- - private int selected_offset_y (unichar item) {- int64 di;- int64 a, b;- - if (unlikely (items_per_row == 0)) {- return 0;- }- - a = (int64) item;- b = (int64) first_visible;- di = (a - b);- - return (int) (view_offset_y + ((di / items_per_row) * nail_height));- }-- /** Make selected item fully visible if it partly off screen. */- private void adjust_scroll () {- int off = selected_offset_y (selected);-- if (off < 0) {- close_menus ();- scroll (-1 * off);- } else if (off > allocation.height - nail_height) {- scroll ((allocation.height - nail_height) - off);- }+ selected = 0;+ first_visible = 0; } public void key_down () {- double l;- Font f;- - if (all_available) {- f = BirdFont.get_current_font ();- l = f.length ();- } else {- l = glyph_range.length ();- }- - update_scrollbar ();+ Font f = BirdFont.get_current_font ();+ int64 len = (all_available) ? f.length () : glyph_range.length (); - if (l == 0) return;- - if (at_bottom ()) {- int len = (int) l;- int s = (int) selected;- - if (len - items_per_row >= s) {- selected += items_per_row; - } else if (s < len) {- selected++;- }- - if (selected >= len) {- selected = len - 1;- }- - adjust_scroll ();- + selected += items_per_row;++ if (at_bottom () && selected + items_per_row > len) { return; } - selected += items_per_row;- - if (selected > rows * items_per_row + first_visible) {- scroll (-nail_height);+ if (selected >= items_per_row * rows) {+ first_visible += items_per_row;+ selected -= items_per_row; } - adjust_scroll ();+ if (first_visible + selected > len) {+ selected = (int) (len - first_visible - 1);+ + if (selected < items_per_row * (rows - 1)) {+ first_visible -= items_per_row;+ selected += items_per_row;+ }+ } } - public void key_up () {- update_scrollbar ();+ public void key_right () {+ Font f = BirdFont.get_current_font ();+ int64 len = (all_available) ? f.length () : glyph_range.length (); - if (selected < first_character) { - warn_if_reached ();- }- - if (selected < first_character + items_per_row) {- scroll_top ();+ if (at_bottom () && selected + items_per_row > len) { return; } - if (selected - items_per_row >= first_character) {- selected -= items_per_row;- if (selected < first_visible) {- scroll (-nail_height);- }- } - - if (first_visible < first_character) {- selected = first_character;- }+ selected += 1; - adjust_scroll ();+ if (selected >= items_per_row * rows) {+ first_visible += items_per_row;+ selected -= items_per_row;+ selected -= 1;+ } - if (first_visible < first_character) {- scroll_top ();+ if (first_visible + selected > glyph_range.length ()) {+ first_visible -= items_per_row;+ selected = (int) (len - first_visible - 1); }- } - - public void open_current_glyph () {- key_press (Key.ENTER); }-- public void select_next_glyph () {- key_press (Key.RIGHT);- }-- public void key_right () { - uint len;- Font f;+ + public void key_up () {+ selected -= items_per_row; - if (all_available) {- f = BirdFont.get_current_font ();- len = f.length ();- } else {- len = glyph_range.length ();+ if (selected < 0) {+ first_visible -= items_per_row;+ selected += items_per_row; } - if (len == 0) return;- - selected++;- - if (selected >= len) {- selected = len - 1;- }-- if (selected_offset_y (selected) > allocation.height - nail_height) {- selected -= items_per_row;- key_down ();- }+ if (first_visible < 0) {+ scroll_top ();+ } } public void key_left () {- if (selected > first_character) {- selected--; - if (selected_offset_y (selected) < 0) {- selected -= items_per_row;- key_up ();- }+ selected -= 1;++ if (selected < 0) {+ first_visible -= items_per_row;+ selected += items_per_row;+ selected += 1; + }++ if (first_visible < 0) {+ scroll_top (); } } @@ -864,7 +486,6 @@ public class OverView : FontDisplay { public override void key_press (uint keyval) { redraw_area (0, 0, allocation.width, allocation.height);- close_menus (); if (KeyBindings.modifier == CTRL) { return;@@ -872,7 +493,7 @@ public class OverView : FontDisplay { switch (keyval) { case Key.ENTER:- open_glyph_signal (get_selected_char ());+ open_current_glyph (); return; case Key.UP:@@ -892,13 +513,13 @@ public class OverView : FontDisplay { return; case Key.PG_UP:- for (int i = 0; i++ < rows; i++) {+ for (int i = 0; i < rows; i++) { key_up (); } return; case Key.PG_DOWN:- for (int i = 0; i++ < rows; i++) {+ for (int i = 0; i < rows; i++) { key_down (); } return;@@ -954,123 +575,37 @@ public class OverView : FontDisplay { DefaultCharacterSet.use_full_unicode_range (full); set_glyph_range (full);- selected = c;+ // DELETE+ //selected = c; set_glyph_range (gr); } public override void double_click (uint button, double ex, double ey) {- selection_click (button, ex, ey);- open_glyph_signal (get_selected_char ());- }+ foreach (OverViewItem i in visible_items) {+ i.double_click (button, ex, ey);+ } - private void selection_click (uint button, double ex, double ey) {- double x = view_offset_x;- double y = view_offset_y;- double px, py;- - // click in margin- int n_items = (allocation.width - 40 / nail_width);- double m = (allocation.width - 40 - (n_items * nail_width)) / 2.0;- - bool menu_action = false;- - Font f;- uint len;- redraw_area (0, 0, allocation.width, allocation.height);+ } - if (character_info != null) {- character_info = null;- return;- }-- if (all_available) {- f = BirdFont.get_current_font ();- len = f.length ();- } else {- len = glyph_range.length ();- }- - px = ex - view_offset_x;- py = ey - view_offset_y;- foreach (GlyphCollection g in get_visible_glyphs ()) {- bool a;- - a = g.get_version_list ().menu_item_action (px, py); // select one item on the menu- - if (a) {- return;- }- - a = g.get_version_list ().menu_icon_action (px, py); // open menu- - if (a) {- menu_action = true;- }- }-- character_info = null;- foreach (CharacterInfo info in unicode_database_info) {- if (info.is_over_icon (px, py)) {- character_info = info;+ public override void button_press (uint button, double x, double y) {+ // DELETE selection_click (button, x, y);+ int index = 0;+ foreach (OverViewItem i in visible_items) {+ if (i.click (button, x, y)) {+ selected = index; }- }- - if (ex < m) {- ex = m + 1;- }- - if (ex > allocation.width - m) {- ex = allocation.width - m - 1;- }- - if (ey < 5) {- ey = 5;- }- - if (ey > allocation.height - 5) {- ey = allocation.height - 5;- } - // empty set- if (len == 0) {- return;- }-- // scroll to the selected glyph- selected = (uint32) first_visible;-- while (y < ey < allocation.height) {- selected += items_per_row;- y += nail_height;- }- selected -= items_per_row;-- while (x < ex < allocation.width) {- selected++;- x += nail_width;- }- - selected--;- - if (at_bottom () && selected >= len) {- selected = len - 1;+ index++; }- - adjust_scroll ();- - adjust_scroll ();- adjust_scroll ();- } - public override void button_press (uint button, double x, double y) {- selection_click (button, x, y);+ redraw_area (0, 0, allocation.width, allocation.height); } /** Returns true if overview shows the last character. */ private bool at_bottom () { Font f;- double t = rows * items_per_row + items_per_row + first_visible;+ double t = rows * items_per_row + first_visible; if (all_available) { f = BirdFont.get_current_font ();@@ -1082,10 +617,7 @@ public class OverView : FontDisplay { public void set_glyph_range (GlyphRange range) { GlyphRange? current = glyph_range;- string c = "";- bool done = false;- uint32 i;- uint32 len = 0;+ string c; if (current != null) { c = glyph_range.get_char (selected);@@ -1094,73 +626,23 @@ public class OverView : FontDisplay { all_available = false; glyph_range = range;-- // Todo: optimized search when full range is selected.- - // scroll to the selected character- if (c == "") {- c = glyph_range.get_char (0);- }-- if (items_per_row == 0) {- return;- }- scroll_top (); - // Skip scroll if this is a unassigned character- if (c.char_count () > 1) {- return;- }-- while (true) {- for (i = (uint32) first_visible; i < first_visible + items_per_row * (rows + 1); i++) {- if (range.get_char (i) == c) {- selected = i;- done = true;- break;- }- }- - if (done) break;- if (at_bottom ()) break;-- scroll_rows (rows);- }-- if (unlikely (!done)) {- Toolbox.select_tool_by_name ("custom_character_set");- warning (@"No glyph \"$c\"\n");- return;- }- - adjust_scroll ();- - if (at_bottom ()) {- while (c != glyph_range.get_char (selected) && glyph_range.get_length () >= items_per_row) {- key_right (); - if (selected >= glyph_range.get_length () - items_per_row) {- break;- }- }+ // TODO: scroll down to c - len = glyph_range.get_length ();- for (i = selected; i < len; i++) {- if (c == glyph_range.get_char (i)) {- break;- }- }-- if (i == len) {- selected = first_character;- scroll_top ();- }- }-- update_scrollbar (); redraw_area (0, 0, allocation.width, allocation.height); } + public void select_next_glyph () {+ key_right ();+ }+ + public void open_current_glyph () + requires (0 <= selected < visible_items.length ()) {+ OverViewItem o = visible_items.nth (selected).data;+ o.edit_glyph ();+ }+ public void update_scrollbar () { Font f; double nrows = 0;new file mode 100644@@ -0,0 +1,282 @@+/*+ Copyright (C) 2012 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 class OverViewItem : GLib.Object {+ public unichar character = 'A'; // FIXME: + public GlyphCollection? glyphs;+ public double x;+ public double y;+ public bool selected = false;+ public CharacterInfo info;+ public bool display_info = false;+ + public static double DEFAULT_WIDTH = 100;+ public static double DEFAULT_HEIGHT = 130;+ public static double DEFAULT_MARGIN = 20;+ + public static double width = 100;+ public static double height = 130;+ public static double margin = 20;+ + public OverViewItem (GlyphCollection? glyphs, unichar character, double x, double y) { + this.x = x;+ this.y = y;+ this.character = character;+ this.glyphs = glyphs;+ this.info = new CharacterInfo (character);+ }+ + public static double full_width () {+ return width + margin;+ }++ public static double full_height () {+ return height + margin;+ }+ + public bool click (uint button, double px, double py) {+ bool a;+ GlyphCollection g;+ selected = (x <= px <= x + width) && (y <= py <= y + height);+ + if (glyphs != null) {+ g = (!) glyphs;+ a = g.get_version_list ().menu_item_action (px, py); // select one item on the menu+ if (a) {+ return selected;+ }+ + g.get_version_list ().menu_icon_action (px, py); // click in the open menu+ }+ + return selected;+ }++ public void double_click (uint button, double px, double py) {+ selected = (x <= px <= x + width) && (y <= py <= y + height);+ + if (selected) {+ edit_glyph ();+ }+ + display_info = info.is_over_icon (px, py);+ }+ + public void edit_glyph () {+ OverView overview = MainWindow.get_overview ();+ + if (glyphs == null) {+ overview.open_new_glyph_signal (character);+ } else {+ overview.open_glyph_signal ((!) glyphs);+ } + }+ + public void draw (Context cr) {+ cr.save ();+ cr.set_source_rgba (1, 1, 1, 1);+ cr.rectangle (x, y, width, height);+ cr.fill ();+ cr.restore ();+ + cr.save ();+ cr.set_source_rgba (0, 0, 0, 1);+ cr.rectangle (x, y, width, height);+ cr.set_line_width (0.5);+ cr.stroke ();+ cr.restore ();+ + draw_thumbnail (cr, glyphs, x, y + height); + draw_caption (cr);+ + if (display_info) {+ draw_character_info (cr);+ } + }++ private bool draw_thumbnail (Context cr, GlyphCollection? gl, double x, double y) {+ Glyph g;+ double gx, gy;+ double x1, x2, y1, y2;+ double scale = width / DEFAULT_WIDTH;+ double w, h;++ w = width;+ h = height;+ + if (gl == null) {+ return false;+ }+ + g = ((!) gl).get_current ();+ g.boundries (out x1, out y1, out x2, out y2);++ gx = (width - (x2 - x1)) / 2*scale;+ + if (gx < 0) {+ gx = 0;+ }+ + gy = (h / scale) - 25 / scale;+ + Surface s = new Surface.similar (cr.get_target (), Content.COLOR_ALPHA, (int) w, (int) h - 20);+ Context c = new Context (s);+ + c.scale (scale, scale); + Svg.draw_svg_path (c, g.get_svg_data (), gx, gy);+ + cr.save ();+ cr.set_source_surface (s, x, y - h);+ cr.paint ();+ cr.restore ();++ return true;+ }++ public void draw_caption (Context cr) {+ cr.save ();+ + if (selected) {+ cr.set_source_rgba (50/255.0, 50/255.0, 50/255.0, 1);+ } else {+ cr.set_source_rgba (100/255.0, 100/255.0, 100/255.0, 1); + }+ + cr.rectangle (x + 1, y + height - 20, width - 2, 20 - 1);+ cr.fill ();+ draw_menu (cr);+ draw_character_info_icon (cr);+ cr.restore ();+ }++ private void draw_character_info_icon (Context cr) {+ double px = x + width - 17;+ double py = y + height - 16;+ info.set_position (px, py);+ info.draw_icon (cr);+ }+ + private void draw_menu (Context cr) {+ GlyphCollection g;+ DropMenu menu;+ + if (glyphs == null) {+ return;+ }+ + g = (!) glyphs;+ + menu = g.get_version_list ();+ menu.set_position (x + width - 32, y + height - 16);+ menu.draw_icon (cr);+ menu.draw_menu (cr);+ }++ /** Display one entry from the Unicode Character Database. */+ void draw_character_info (Context cr) {+ double x, y, w, h;+ int i;+ string unicode_value, unicode_description;+ string[] column;+ string entry;+ int len = 0;+ int length = 0;+ bool see_also = false;+ Allocation allocation = MainWindow.get_overview ().allocation;+ + entry = info.get_entry ();+ + foreach (string line in entry.split ("\n")) {+ len = line.char_count ();+ if (len > length) {+ length = len;+ }+ }+ + x = allocation.width * 0.1;+ y = allocation.height * 0.1;+ w = allocation.width * 0.9 - x; + h = allocation.height * 0.9 - y;+ + if (w < 8 * length) {+ w = 8 * length;+ x = (allocation.width - w) / 2.0;+ }+ + // background + cr.save ();+ cr.set_source_rgba (1, 1, 1, 0.8);+ cr.rectangle (x, y, w, h);+ cr.fill ();+ cr.restore ();++ cr.save ();+ cr.set_source_rgba (0, 0, 0, 0.8);+ cr.set_line_width (2);+ cr.rectangle (x, y, w, h);+ cr.stroke ();+ cr.restore ();++ // database entry+ i = 0;+ foreach (string line in entry.split ("\n")) {+ if (i == 0) {+ column = line.split ("\t");+ return_if_fail (column.length == 2);+ unicode_value = "U+" + column[0];+ unicode_description = column[1];++ draw_info_line (unicode_description, cr, x, y, i);+ i++;++ draw_info_line (unicode_value, cr, x, y, i);+ i++; + } else {+ + if (line.has_prefix ("\t*")) {+ draw_info_line (line.replace ("\t*", "•"), cr, x, y, i);+ i++; + } else if (line.has_prefix ("\tx (")) {+ if (!see_also) {+ i++;+ draw_info_line (_("See also:"), cr, x, y, i);+ i++;+ see_also = true;+ }+ + draw_info_line (line.replace ("\tx (", "•").replace (")", ""), cr, x, y, i);+ i++;+ } else {++ i++;+ }+ }+ }+ }++ void draw_info_line (string line, Context cr, double x, double y, int row) {+ cr.save ();+ cr.set_font_size (12);+ cr.set_source_rgba (0, 0, 0, 1);+ cr.move_to (x + 10, y + 28 + row * 18 * 1.2);+ cr.show_text (line);+ cr.restore (); + }+}++}