From 8b3e44750bb9a53815b31d9a73053425d5f794ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 20 Jul 2026 13:04:29 -0700 Subject: [PATCH 1/3] FormatBar: move lang popover construction to construct --- src/Widgets/FormatBar.vala | 101 ++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/src/Widgets/FormatBar.vala b/src/Widgets/FormatBar.vala index 9e2e57b16..f7cf19316 100644 --- a/src/Widgets/FormatBar.vala +++ b/src/Widgets/FormatBar.vala @@ -30,7 +30,6 @@ public class Code.FormatBar : Gtk.Box { private Granite.SwitchModelButton space_tab_modelbutton; private Gtk.Entry goto_entry; private Gtk.ListBox lang_selection_listbox; - private Gtk.SearchEntry lang_selection_filter; private Gtk.SourceLanguageManager manager; private LangEntry normal_entry; @@ -45,8 +44,48 @@ public class Code.FormatBar : Gtk.Box { icon = new ThemedIcon ("format-indent-more-symbolic") }; + var lang_selection_filter = new Gtk.SearchEntry () { + margin_top = 12, + margin_bottom = 6, + margin_start = 12, + margin_end = 12, + placeholder_text = _("Filter languages") + }; + + lang_selection_listbox = new Gtk.ListBox () { + selection_mode = SINGLE + }; + lang_selection_listbox.set_sort_func ((row1, row2) => { + return ((LangEntry) row1).lang_name.collate (((LangEntry) row2).lang_name); + }); + lang_selection_listbox.set_filter_func ((row) => { + //Both are lowercased so that the case doesn't matter when comparing. + return (((LangEntry) row).lang_name.down ().contains (lang_selection_filter.text.down ().strip ())); + }); + + var lang_scrolled = new Gtk.ScrolledWindow (null, null) { + child = lang_selection_listbox, + hscrollbar_policy = NEVER, + height_request = 350, + hexpand = true, + vexpand = true, + margin_top = 3, + margin_bottom = 3 + }; + + var popover_content = new Gtk.Box (VERTICAL, 0); + popover_content.add (lang_selection_filter); + popover_content.add (lang_scrolled); + popover_content.show_all (); + + var lang_popover = new Gtk.Popover (lang_menubutton) { + position = BOTTOM, + child = popover_content + }; + lang_menubutton = new FormatButton () { icon = new ThemedIcon ("application-x-class-file-symbolic"), + popover = lang_popover, tooltip_text = _("Document language") }; @@ -66,46 +105,7 @@ public class Code.FormatBar : Gtk.Box { add (line_menubutton); create_tabulation_popover (); - create_language_popover (); create_line_popover (); - } - - public void activate_line_menubutton () { - line_menubutton.active = true; - } - - private void create_language_popover () { - lang_selection_listbox = new Gtk.ListBox (); - lang_selection_listbox.selection_mode = Gtk.SelectionMode.SINGLE; - lang_selection_listbox.set_sort_func ((row1, row2) => { - return ((LangEntry) row1).lang_name.collate (((LangEntry) row2).lang_name); - }); - lang_selection_listbox.set_filter_func ((row) => { - //Both are lowercased so that the case doesn't matter when comparing. - return (((LangEntry) row).lang_name.down ().contains (lang_selection_filter.text.down ().strip ())); - }); - - lang_selection_filter = new Gtk.SearchEntry () { - margin_top = 12, - margin_bottom = 6, - margin_start = 12, - margin_end = 12, - placeholder_text = _("Filter languages") - }; - - lang_selection_filter.changed.connect (() => { - lang_selection_listbox.invalidate_filter (); - }); - - var lang_scrolled = new Gtk.ScrolledWindow (null, null) { - hscrollbar_policy = Gtk.PolicyType.NEVER, - height_request = 350, - hexpand = true, - vexpand = true, - margin_top = 3, - margin_bottom = 3, - child = lang_selection_listbox - }; unowned string[]? ids = manager.get_language_ids (); unowned SList group = null; @@ -117,24 +117,21 @@ public class Code.FormatBar : Gtk.Box { } normal_entry = new LangEntry (null, _("Plain Text"), group); - lang_selection_listbox.add (normal_entry); - - var popover_content = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); - popover_content.add (lang_selection_filter); - popover_content.add (lang_scrolled); - popover_content.show_all (); - - var lang_popover = new Gtk.Popover (lang_menubutton) { - position = Gtk.PositionType.BOTTOM, - child = popover_content - }; - lang_menubutton.popover = lang_popover; + lang_selection_listbox.add (normal_entry); lang_selection_listbox.row_activated.connect ((row) => { var lang_entry = ((LangEntry) row); select_language (lang_entry); }); + + lang_selection_filter.changed.connect (() => { + lang_selection_listbox.invalidate_filter (); + }); + } + + public void activate_line_menubutton () { + line_menubutton.active = true; } private void select_language (LangEntry lang, bool update_source_view = true) { From 04409cc57234c9b74225ce520efc07d98bb310fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 20 Jul 2026 13:18:21 -0700 Subject: [PATCH 2/3] FormatBar: move tab width popover construction to construct --- src/Widgets/FormatBar.vala | 138 ++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 70 deletions(-) diff --git a/src/Widgets/FormatBar.vala b/src/Widgets/FormatBar.vala index f7cf19316..4a5cdfb16 100644 --- a/src/Widgets/FormatBar.vala +++ b/src/Widgets/FormatBar.vala @@ -20,17 +20,16 @@ public class Code.FormatBar : Gtk.Box { public bool tab_style_set_by_editor_config { get; set; default = false; } public bool tab_width_set_by_editor_config { get; set; default = false; } - public Gtk.InfoBar editorconfig_infobar { get; set construct; } - public Gtk.Box tab_box { get; set construct; } - public Gtk.SpinButton width_spinbutton { get; set construct; } private FormatButton line_menubutton; private FormatButton lang_menubutton; private FormatButton tab_menubutton; private Granite.SwitchModelButton space_tab_modelbutton; private Gtk.Entry goto_entry; + private Gtk.InfoBar editorconfig_infobar; private Gtk.ListBox lang_selection_listbox; private Gtk.SourceLanguageManager manager; + private Gtk.SpinButton width_spinbutton; private LangEntry normal_entry; private unowned Scratch.Services.Document? doc = null; @@ -40,8 +39,51 @@ public class Code.FormatBar : Gtk.Box { manager = Gtk.SourceLanguageManager.get_default (); + editorconfig_infobar = new Gtk.InfoBar () { + margin_top = 9, + margin_end = 9, + margin_start = 9 + }; + editorconfig_infobar.get_content_area ().add (new Gtk.Label (_("Some settings set by EditorConfig file"))); + editorconfig_infobar.get_style_context ().add_class (Gtk.STYLE_CLASS_FRAME); + + var autoindent_modelbutton = new Granite.SwitchModelButton (_("Automatic Indentation")); + + space_tab_modelbutton = new Granite.SwitchModelButton (_("Insert Spaces Instead Of Tabs")); + + width_spinbutton = new Gtk.SpinButton.with_range (2, 16, 1); + + var width_label = new Gtk.Label (_("Tab width")) { + halign = START, + hexpand = true, + mnemonic_widget = width_spinbutton + }; + + var tab_box = new Gtk.Box (HORIZONTAL, 12) { + margin_top = 6, + margin_end = 12, + margin_start = 12, + }; + tab_box.add (width_label); + tab_box.add (width_spinbutton); + + var box = new Gtk.Box (VERTICAL, 0) { + margin_bottom = 12 + }; + box.add (editorconfig_infobar); + box.add (autoindent_modelbutton); + box.add (space_tab_modelbutton); + box.add (tab_box); + box.show_all (); + + var tab_popover = new Gtk.Popover (null) { + position = BOTTOM, + child = box + }; + tab_menubutton = new FormatButton () { - icon = new ThemedIcon ("format-indent-more-symbolic") + icon = new ThemedIcon ("format-indent-more-symbolic"), + popover = tab_popover }; var lang_selection_filter = new Gtk.SearchEntry () { @@ -78,7 +120,7 @@ public class Code.FormatBar : Gtk.Box { popover_content.add (lang_scrolled); popover_content.show_all (); - var lang_popover = new Gtk.Popover (lang_menubutton) { + var lang_popover = new Gtk.Popover (null) { position = BOTTOM, child = popover_content }; @@ -104,7 +146,6 @@ public class Code.FormatBar : Gtk.Box { add (lang_menubutton); add (line_menubutton); - create_tabulation_popover (); create_line_popover (); unowned string[]? ids = manager.get_language_ids (); @@ -128,69 +169,6 @@ public class Code.FormatBar : Gtk.Box { lang_selection_filter.changed.connect (() => { lang_selection_listbox.invalidate_filter (); }); - } - - public void activate_line_menubutton () { - line_menubutton.active = true; - } - - private void select_language (LangEntry lang, bool update_source_view = true) { - lang_selection_listbox.select_row (lang); - lang_menubutton.text = lang.lang_name; - if (update_source_view) { - lang.active = true; - doc.source_view.language = lang.lang_id != null ? manager.get_language (lang.lang_id) : null; - } else { - lang.selected = true; - } - } - - private void create_tabulation_popover () { - editorconfig_infobar = new Gtk.InfoBar () { - margin_top = 9, - margin_end = 9, - margin_start = 9 - }; - editorconfig_infobar.get_content_area ().add (new Gtk.Label (_("Some settings set by EditorConfig file"))); - editorconfig_infobar.get_style_context ().add_class (Gtk.STYLE_CLASS_FRAME); - - var autoindent_modelbutton = new Granite.SwitchModelButton (_("Automatic Indentation")); - - space_tab_modelbutton = new Granite.SwitchModelButton (_("Insert Spaces Instead Of Tabs")); - - var width_label = new Gtk.Label (_("Tab width")) { - halign = Gtk.Align.START, - hexpand = true - }; - - width_spinbutton = new Gtk.SpinButton.with_range (2, 16, 1); - - tab_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12) { - margin_top = 6, - margin_end = 12, - margin_start = 12, - }; - tab_box.add (width_label); - tab_box.add (width_spinbutton); - - var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - margin_bottom = 12 - }; - box.add (editorconfig_infobar); - box.add (autoindent_modelbutton); - box.add (space_tab_modelbutton); - box.add (tab_box); - box.show_all (); - - var tab_popover = new Gtk.Popover (tab_menubutton) { - position = Gtk.PositionType.BOTTOM, - child = box - }; - tab_menubutton.popover = tab_popover; - - Scratch.settings.changed["indent-width"].connect (format_tab_header_from_global_settings); - Scratch.settings.changed["spaces-instead-of-tabs"].connect (format_tab_header_from_global_settings); - Scratch.settings.bind ("auto-indent", autoindent_modelbutton, "active", SettingsBindFlags.DEFAULT); format_tab_header_from_global_settings (); width_spinbutton.value_changed.connect (() => { @@ -210,6 +188,27 @@ public class Code.FormatBar : Gtk.Box { ); } }); + + Scratch.settings.changed["indent-width"].connect (format_tab_header_from_global_settings); + Scratch.settings.changed["spaces-instead-of-tabs"].connect (format_tab_header_from_global_settings); + Scratch.settings.bind ("auto-indent", autoindent_modelbutton, "active", DEFAULT); + + bind_property ("tab-width-set-by-editor-config", tab_box, "sensitive", INVERT_BOOLEAN | SYNC_CREATE); + } + + public void activate_line_menubutton () { + line_menubutton.active = true; + } + + private void select_language (LangEntry lang, bool update_source_view = true) { + lang_selection_listbox.select_row (lang); + lang_menubutton.text = lang.lang_name; + if (update_source_view) { + lang.active = true; + doc.source_view.language = lang.lang_id != null ? manager.get_language (lang.lang_id) : null; + } else { + lang.selected = true; + } } private void format_tab_header_from_global_settings () { @@ -223,7 +222,6 @@ public class Code.FormatBar : Gtk.Box { editorconfig_infobar.revealed = tab_style_set_by_editor_config || tab_width_set_by_editor_config; space_tab_modelbutton.sensitive = !tab_style_set_by_editor_config; - tab_box.sensitive = !tab_width_set_by_editor_config; } private void format_line_header () { From fd3f68e0a3cae3f504a8c99284d1c2f2c2b321f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 20 Jul 2026 13:27:23 -0700 Subject: [PATCH 3/3] FormatBar: move goto line popover construction to construct --- src/Widgets/FormatBar.vala | 95 ++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 50 deletions(-) diff --git a/src/Widgets/FormatBar.vala b/src/Widgets/FormatBar.vala index 4a5cdfb16..8286caefc 100644 --- a/src/Widgets/FormatBar.vala +++ b/src/Widgets/FormatBar.vala @@ -105,6 +105,18 @@ public class Code.FormatBar : Gtk.Box { return (((LangEntry) row).lang_name.down ().contains (lang_selection_filter.text.down ().strip ())); }); + unowned SList group = null; + foreach (unowned string id in manager.get_language_ids ()) { + weak Gtk.SourceLanguage lang = manager.get_language (id); + var entry = new LangEntry (id, lang.name, group); + group = entry.get_radio_group (); + lang_selection_listbox.add (entry); + } + + normal_entry = new LangEntry (null, _("Plain Text"), group); + + lang_selection_listbox.add (normal_entry); + var lang_scrolled = new Gtk.ScrolledWindow (null, null) { child = lang_selection_listbox, hscrollbar_policy = NEVER, @@ -131,8 +143,30 @@ public class Code.FormatBar : Gtk.Box { tooltip_text = _("Document language") }; + goto_entry = new Gtk.Entry (); + + var goto_label = new Gtk.Label (_("Go To Line:")) { + mnemonic_widget = goto_entry + }; + + var line_box = new Gtk.Box (HORIZONTAL, 12) { + margin_top = 12, + margin_bottom = 12, + margin_start = 12, + margin_end = 12 + }; + line_box.add (goto_label); + line_box.add (goto_entry); + line_box.show_all (); + + var line_popover = new Gtk.Popover (null) { + position = BOTTOM, + child = line_box + }; + line_menubutton = new FormatButton () { - icon = new ThemedIcon ("view-continuous-symbolic") + icon = new ThemedIcon ("view-continuous-symbolic"), + popover = line_popover }; line_menubutton.tooltip_markup = Granite.markup_accel_tooltip ( ((Scratch.Application) GLib.Application.get_default ()).get_accels_for_action ( @@ -146,21 +180,6 @@ public class Code.FormatBar : Gtk.Box { add (lang_menubutton); add (line_menubutton); - create_line_popover (); - - unowned string[]? ids = manager.get_language_ids (); - unowned SList group = null; - foreach (unowned string id in ids) { - weak Gtk.SourceLanguage lang = manager.get_language (id); - var entry = new LangEntry (id, lang.name, group); - group = entry.get_radio_group (); - lang_selection_listbox.add (entry); - } - - normal_entry = new LangEntry (null, _("Plain Text"), group); - - lang_selection_listbox.add (normal_entry); - lang_selection_listbox.row_activated.connect ((row) => { var lang_entry = ((LangEntry) row); select_language (lang_entry); @@ -189,6 +208,16 @@ public class Code.FormatBar : Gtk.Box { } }); + // We need to connect_after because otherwise, the text isn't parsed into the "value" property and we only get the previous value + goto_entry.activate.connect_after (() => { + int line, column; + goto_entry.text = goto_entry.text.replace (":", "."); + goto_entry.text.scanf ("%i.%i", out line, out column); + doc.source_view.go_to_line (line, column - 1); + // Focuses parent to the source view, so that the cursor, which indicates line and column is actually visible. + doc.source_view.grab_focus (); + }); + Scratch.settings.changed["indent-width"].connect (format_tab_header_from_global_settings); Scratch.settings.changed["spaces-instead-of-tabs"].connect (format_tab_header_from_global_settings); Scratch.settings.bind ("auto-indent", autoindent_modelbutton, "active", DEFAULT); @@ -234,40 +263,6 @@ public class Code.FormatBar : Gtk.Box { goto_entry.text = "%d.%d".printf (line, iter.get_line_offset () + 1); } - private void create_line_popover () { - var goto_label = new Gtk.Label (_("Go To Line:")); - goto_label.xalign = 1; - - goto_entry = new Gtk.Entry (); - - var line_grid = new Gtk.Grid () { - margin_top = 12, - margin_bottom = 12, - margin_start = 12, - margin_end = 12 - }; - line_grid.column_spacing = 12; - line_grid.attach (goto_label, 0, 0, 1, 1); - line_grid.attach (goto_entry, 1, 0, 1, 1); - line_grid.show_all (); - - var line_popover = new Gtk.Popover (line_menubutton) { - position = Gtk.PositionType.BOTTOM, - child = line_grid - }; - line_menubutton.popover = line_popover; - - // We need to connect_after because otherwise, the text isn't parsed into the "value" property and we only get the previous value - goto_entry.activate.connect_after (() => { - int line, column; - goto_entry.text = goto_entry.text.replace (":", "."); - goto_entry.text.scanf ("%i.%i", out line, out column); - doc.source_view.go_to_line (line, column - 1); - // Focuses parent to the source view, so that the cursor, which indicates line and column is actually visible. - doc.source_view.grab_focus (); - }); - } - public void set_document (Scratch.Services.Document doc) { if (this.doc != null) { this.doc.source_view.buffer.notify["cursor-position"].disconnect (format_line_header);