Commit ca32c33
Platform independent text input
Changed files (21)
modifiedlibbirdfont/FileDialogTab.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/KerningDisplay.valamodifiedlibbirdfont/KerningRange.valamodifiedlibbirdfont/LigatureList.valamodifiedlibbirdfont/Ligatures.valamodifiedlibbirdfont/Line.valamodifiedlibbirdfont/MainWindow.valamodifiedlibbirdfont/MenuTab.valamodifiedlibbirdfont/NativeWindow.valamodifiedlibbirdfont/OpenFontFormat/Ligature.valamodifiedlibbirdfont/OverView.valamodifiedlibbirdfont/Renderer/LineTextArea.valamodifiedlibbirdfont/Renderer/TextArea.valamodifiedlibbirdfont/SpacingClass.valamodifiedlibbirdfont/SpacingClassTab.valamodifiedlibbirdfont/SpacingTab.valamodifiedlibbirdfont/SpinButton.valamodifiedlibbirdfont/TabBar.valamodifiedlibbirdfont/TabContent.valamodifiedlibbirdfont/Toolbox.vala
Diff
@@ -137,7 +137,7 @@ public class FileDialogTab : FontDisplay { } }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } public override void draw (WidgetAllocation allocation, Context cr) {@@ -2142,11 +2142,11 @@ public class Glyph : FontDisplay { BirdFont.get_current_font ().custom_guides.add (guide); - MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); GlyphCanvas.redraw (); }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } } @@ -638,7 +638,7 @@ public class KerningDisplay : FontDisplay { listener.signal_submit.connect (() => { unichar c;- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); text_input = false; suppress_input = false;@@ -653,7 +653,7 @@ public class KerningDisplay : FontDisplay { suppress_input = true; text_input = true;- MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } public void new_line () {@@ -836,14 +836,14 @@ public class KerningDisplay : FontDisplay { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); text_input = false; suppress_input = false; }); suppress_input = true; text_input = true;- MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); GlyphCanvas.redraw (); }@@ -108,7 +108,7 @@ public class KerningRange : Tool { listener.signal_submit.connect (() => { MainWindow.get_kerning_display ().suppress_input = false;- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); // remove all empty classes if (ranges == "") {@@ -119,7 +119,7 @@ public class KerningRange : Tool { kerning_display.suppress_input = true; - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } public override void draw (Context cr) {@@ -49,11 +49,11 @@ public class LigatureList : Table { if (row.get_index () == NEW_LIGATURE && column == 0) { add_ligature (t_("character sequence"), t_("ligature"));- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); } else if (row.get_index () == NEW_LIGATURE && column == 1) { if (BirdFont.has_argument ("--test")) { add_contextual_ligature (t_("beginning"), t_("middle"), t_("end"));- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); } } else if (row.has_row_data ()) { i = row.get_index ();@@ -71,7 +71,7 @@ public class LigatureList : Table { if (delete_button) { return_if_fail (0 <= row.get_index () < ligatures.count ()); ligatures.remove_at (row.get_index ());- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); } else if (column == 0) { return_if_fail (0 <= row.get_index () < ligatures.count ()); ligatures.set_ligature (row.get_index ());@@ -86,7 +86,7 @@ public class LigatureList : Table { return_if_fail (0 <= i < ligatures.count_contextual_ligatures ()); if (delete_button) { ligatures.remove_contextual_ligatures_at (i);- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); } else if (column == 0) { ligatures.set_beginning (i); } else if (column == 1) {@@ -113,11 +113,11 @@ public class Ligatures : GLib.Object { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); MainWindow.get_ligature_display ().update_rows (); }); - MainWindow.native_window.set_text_listener (listener); + TabContent.show_text_input (listener); } public void set_middle (int index) {@@ -134,11 +134,11 @@ public class Ligatures : GLib.Object { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); MainWindow.get_ligature_display ().update_rows (); }); - MainWindow.native_window.set_text_listener (listener); + TabContent.show_text_input (listener); } public void set_end (int index) {@@ -155,11 +155,11 @@ public class Ligatures : GLib.Object { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); MainWindow.get_ligature_display ().update_rows (); }); - MainWindow.native_window.set_text_listener (listener); + TabContent.show_text_input (listener); } public void set_ligature (int index) {@@ -151,10 +151,10 @@ public class Line : GLib.Object { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } else { move = true; }@@ -205,9 +205,9 @@ public class MainWindow : GLib.Object { GlyphCanvas.redraw (); }); listener.signal_submit.connect (() => { - MainWindow.native_window.hide_text_input (); + TabContent.hide_text_input (); }); - native_window.set_text_listener (listener); + TabContent.show_text_input (listener); } public static MainWindow get_singleton () { @@ -266,7 +266,7 @@ public class MenuTab : FontDisplay { return; } - MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); SaveDialogListener dialog = new SaveDialogListener (); Font font = BirdFont.get_current_font ();@@ -553,11 +553,11 @@ public class MenuTab : FontDisplay { o.display_all_available_glyphs (); o.scroll_to_glyph (ligature_name); - MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); show_all_available_characters (); }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } public static void show_default_characters () {@@ -27,12 +27,6 @@ public interface NativeWindow : GLib.Object { public abstract void set_scrollbar_size (double size); public abstract void set_scrollbar_position (double position);- - /** Request text input from the UI. */- public abstract void set_text_listener (TextListener listener);- - /** Remove the text listener and hode the text area. */- public abstract void hide_text_input (); /** Show overwrite dialog */ public abstract void set_overwrite_dialog (OverWriteDialogListener dialog);@@ -37,11 +37,11 @@ public class Ligature : GLib.Object { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); MainWindow.get_ligature_display ().update_rows (); }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } public void set_substitution (ContextualLigature? clig = null) {@@ -62,11 +62,11 @@ public class Ligature : GLib.Object { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); MainWindow.get_ligature_display ().update_rows (); }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } } @@ -172,11 +172,11 @@ public class OverView : FontDisplay { OverView o = MainWindow.get_overview (); GlyphRange r = CharDatabase.search (o.search_query); o.set_glyph_range (r);- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); MainWindow.get_tab_bar ().select_tab_name ("Overview"); }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } public Glyph? get_current_glyph () {@@ -21,9 +21,11 @@ public class LineTextArea : TextArea { public LineTextArea (double size) { base (size);+ single_line = true; min_height = size; height = min_height;+ layout (); } }@@ -48,6 +48,7 @@ public class TextArea : Widget { public signal void scroll (double pixels); public signal void text_changed (string text);+ public signal void enter (string text); Gee.ArrayList<Paragraph> paragraphs = new Gee.ArrayList<Paragraph> (); private static const int DONE = -2; @@ -205,6 +206,10 @@ public class TextArea : Widget { case Key.ENTER: store_undo_edit_state (); insert_text ("\n");+ + if (single_line) {+ enter (get_text ());+ } break; case Key.DEL: if (has_selection ()) {@@ -825,11 +830,7 @@ public class TextArea : Widget { tx = 0; ty = font_size;-- if (unlikely (allocation.height == 0)) {- warning ("Allocation is not set.");- }-+ for (i = paragraphs.size - 1; i >= 0 && paragraphs.size > 1; i--) { if (unlikely (paragraphs.get (i).is_empty ())) { warning ("Empty paragraph.");@@ -1564,8 +1565,15 @@ public class TextArea : Widget { public int paragraph = 0; public int character_index {- get { return ci; }- set { if (value == 0) b(); ci = value; }+ get { + return ci;+ }+ + set { + if (value == 0) {+ ci = value;+ }+ } } private int ci = 0;@@ -1573,9 +1581,6 @@ public class TextArea : Widget { public double desired_x = 0; public double desired_y = 0; - public void b () {- }- public Carret () { } @@ -61,10 +61,10 @@ public class SpacingClass : GLib.Object { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } } @@ -34,7 +34,7 @@ public class SpacingClassTab : Table { if (row.get_index () == -1) { spacing.add_class ("?", "?");- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); update_rows (); update_scrollbar (); font.touch ();@@ -42,7 +42,7 @@ public class SpacingClassTab : Table { if (delete_button) { return_if_fail (0 <= row.get_index () < spacing.classes.size); spacing.classes.remove_at (row.get_index ());- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); update_rows (); update_scrollbar (); font.touch ();@@ -219,7 +219,7 @@ public class SpacingTab : KerningDisplay { listener.signal_submit.connect (() => { double v;- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); text_input = false; suppress_input = false;@@ -230,7 +230,7 @@ public class SpacingTab : KerningDisplay { suppress_input = true; text_input = true;- MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } void update_rsb (Glyph? g) {@@ -256,7 +256,7 @@ public class SpacingTab : KerningDisplay { listener.signal_submit.connect (() => { double v;- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); text_input = false; suppress_input = false;@@ -267,7 +267,7 @@ public class SpacingTab : KerningDisplay { suppress_input = true; text_input = true;- MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } } @@ -202,11 +202,11 @@ public class SpinButton : Tool { }); listener.signal_submit.connect (() => {- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); redraw (); }); - MainWindow.native_window.set_text_listener (listener);+ TabContent.show_text_input (listener); } public void set_max (double max) {@@ -411,7 +411,7 @@ public class TabBar : GLib.Object { } // always close any pending text input if the user switches tab- MainWindow.native_window.hide_text_input ();+ TabContent.hide_text_input (); if (index == SHOW_MENU) { MainWindow.get_menu ().show_menu = !MainWindow.get_menu ().show_menu;@@ -19,6 +19,11 @@ namespace BirdFont { /** Interface for events from native window to the current tab. */ public class TabContent : GLib.Object { + static Text text_input_label;+ static LineTextArea text_input;+ static Button text_input_button;+ static bool text_input_visible = false;+ public static void zoom_in () { if (MenuTab.suppress_event) { }@@ -89,6 +94,10 @@ public class TabContent : GLib.Object { GlyphCanvas.current_display.update_scrollbar (); FontDisplay.dirty_scrollbar = false; }+ + if (text_input_visible) {+ draw_text_input (allocation, cr);+ } } } @@ -99,17 +108,24 @@ public class TabContent : GLib.Object { KeyBindings.add_modifier_from_keyval (keyval); - MainWindow.get_menu ().process_key_binding_events (keyval);- GlyphCanvas.current_display.key_press (keyval);+ if (!text_input_visible) {+ MainWindow.get_menu ().process_key_binding_events (keyval);+ GlyphCanvas.current_display.key_press (keyval);+ } else {+ text_input.key_press (keyval);+ } } public static void key_release (uint keyval) { if (MenuTab.suppress_event) { return; }- - GlyphCanvas.current_display.key_release (keyval);+ KeyBindings.remove_modifier_from_keyval (keyval);++ if (!text_input_visible) {+ GlyphCanvas.current_display.key_release (keyval);+ } } public static void motion_notify (double x, double y) {@@ -117,7 +133,11 @@ public class TabContent : GLib.Object { return; } - GlyphCanvas.current_display.motion_notify (x, y);+ if (!text_input_visible) {+ GlyphCanvas.current_display.motion_notify (x, y);+ } else {+ text_input.motion (x, y);+ } } public static void button_release (int button, double x, double y) {@@ -129,6 +149,10 @@ public class TabContent : GLib.Object { MainWindow.get_menu ().button_release (button, x, y); } else { GlyphCanvas.current_display.button_release (button, x, y);+ + if (text_input_visible) {+ text_input.button_release (button, x, y);+ } } } @@ -141,6 +165,11 @@ public class TabContent : GLib.Object { MainWindow.get_dialog ().button_press (button, x, y); } else if (!MainWindow.get_menu ().show_menu) { GlyphCanvas.current_display.button_press (button, x, y);+ + if (text_input_visible) {+ text_input.button_press (button, x, y);+ text_input_button.button_press (button, x, y);+ } } } @@ -245,6 +274,66 @@ public class TabContent : GLib.Object { return uri; }+ + public static void draw_text_input (WidgetAllocation allocation, Context cr) {+ cr.save ();+ Theme.color (cr, "Background 4");+ cr.rectangle (0, 0, allocation.width, 51);+ cr.fill ();+ cr.restore ();+ + Theme.text_color (text_input_label, "Background 1");+ + text_input_label.allocation = allocation;+ text_input_label.widget_x = 10;+ text_input_label.widget_y = 17;++ text_input.allocation = allocation;+ text_input.widget_x = text_input_label.get_extent () + 20;+ text_input.widget_y = 10;+ text_input.width = allocation.width + - text_input_button.get_width () + - text_input_label.get_extent ()+ - 40;+ + text_input_button.allocation = allocation;+ text_input_button.widget_x = text_input.widget_x + text_input.width + 10;+ text_input_button.widget_y = 10;++ text_input_label.draw (cr);+ text_input.draw (cr);+ text_input_button.draw (cr);+ }+ + public static void show_text_input (TextListener tl) {+ text_input_label = new Text (tl.label);+ text_input = new LineTextArea (20 * MainWindow.units);+ text_input_button = new Button (tl.button_label);+ + text_input.carret_is_visible = true;+ + text_input.set_text (tl.default_text);+ text_input.text_changed.connect ((text) => {+ tl.signal_text_input (text);+ });+ + text_input.enter.connect ((text) => {+ tl.signal_submit (text);+ text_input_visible = false;+ GlyphCanvas.redraw ();+ });+ + text_input_button.action.connect (() => {+ tl.signal_submit (text_input.get_text ());+ });+ + text_input_visible = true;+ GlyphCanvas.redraw ();+ }+ + public static void hide_text_input () {+ text_input_visible = false;+ } } }@@ -47,9 +47,7 @@ public class Toolbox : GLib.Object { static double scale = 1; - public Toolbox (GlyphCanvas glyph_canvas, TabBar tab_bar) { - scale = Toolbox.allocation_width / 160.0;- + public Toolbox (GlyphCanvas glyph_canvas, TabBar tab_bar) { current_tool = new Tool ("no_icon"); press_tool = new Tool (null); @@ -109,6 +107,9 @@ public class Toolbox : GLib.Object { if (w != allocation_width || allocation_height != h) { allocation_width = w; allocation_height = h;+ + scale = Toolbox.allocation_width / 160.0;+ Toolbox.redraw_tool_box (); } }@@ -381,7 +382,7 @@ public class Toolbox : GLib.Object { b.select_tool (b.get_tool (name)); } - public static bool set_scale (double s) {+ public static void set_scale (double s) { scale = s; }