Skip to content

Navigation Menu

Sign in
Sign up

Gtk4Prep: Use ListStore in ProjectChooserButton #1787

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
jeremypw wants to merge 8 commits into master
base: master
Choose a base branch
Loading
from jeremypw/chooseprojectbutton/use-liststore
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/Services/GitManager.vala
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ namespace Scratch.Services {
private static Once<GitManager> instance;
private Gee.HashMap<string, MonitoredRepository> project_gitrepo_map;





construct {
// Used to populate the ChooseProject popover in sorted order
Ggit.init ();
Expand Down
113 changes: 41 additions & 72 deletions src/Widgets/ChooseProjectButton.vala
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ public class Code.ChooseProjectButton : Gtk.Bin {
private const string PROJECT_TOOLTIP = N_("Active Git Project: %s");
private Gtk.Label label_widget;
private Gtk.ListBox project_listbox;

public signal void project_chosen ();
private Gtk.SearchEntry project_filter;
private ListStore project_liststore;
private Scratch.Services.GitManager git_manager;
private Gtk.MenuButton menu_button;

construct {
var img = new Gtk.Image.from_icon_name ("git-symbolic", SMALL_TOOLBAR);
Expand All @@ -35,11 +37,19 @@ public class Code.ChooseProjectButton : Gtk.Bin {
box.add (label_widget);
box.add (cloning_spinner);

git_manager = Scratch.Services.GitManager.get_instance ();
project_liststore = git_manager.project_liststore;
project_listbox = new Gtk.ListBox () {
selection_mode = SINGLE
};

var project_filter = new Gtk.SearchEntry () {
//TODO Use list of objects not widgets
project_listbox.bind_model (project_liststore, (obj) => {
var path = ((Scratch.FolderManager.Item) obj).path;
return new ProjectRow (path);
});

project_filter = new Gtk.SearchEntry () {
margin_top = 12,
margin_bottom = 6,
margin_start = 12,
Expand All @@ -48,8 +58,8 @@ public class Code.ChooseProjectButton : Gtk.Bin {
};

project_listbox.set_filter_func ((row) => {
//Both are lowercased so that the case doesn't matter when comparing.
return (((ProjectRow) row).project_name.down ().contains (project_filter.text.down ().strip ()));
var name = Path.get_basename (((ProjectRow) row).project_path);
return name.contains (project_filter.text); //TODO Is "has_prefix" more useful?
});

project_filter.changed.connect (() => {
Expand Down Expand Up @@ -90,108 +100,62 @@ public class Code.ChooseProjectButton : Gtk.Bin {
child = popover_content
};

var menu_button = new Gtk.MenuButton () {
menu_button = new Gtk.MenuButton () {
child = box,
popover = project_popover
};

child = menu_button;

// Initialise with any pre-existing projects (needed for second and subsequent window)
var git_manager = Scratch.Services.GitManager.get_instance ();
var src = git_manager.project_liststore;
for (int index = 0; index < src.n_items; index++) {
var item = src.get_object (index);
if (item is Scratch.FolderManager.ProjectFolderItem) {
var row = create_project_row ((Scratch.FolderManager.ProjectFolderItem)item);
project_listbox.insert (row, index);
}
}

git_manager.project_liststore.items_changed.connect ((src, pos, n_removed, n_added) => {
var rows = project_listbox.get_children ();
for (int index = (int)pos; index < pos + n_removed; index++) {
var row = rows.nth_data (index);
row.destroy ();
}

for (int index = (int)pos; index < pos + n_added; index++) {
var item = src.get_object (index);
if (item is Scratch.FolderManager.ProjectFolderItem) {
var row = create_project_row ((Scratch.FolderManager.ProjectFolderItem)item);
project_listbox.insert (row, index);
}
}
});
git_manager.notify["active-project-path"].connect (menu_button.popover.popdown);
menu_button.clicked.connect (update_active_project);

menu_button.toggled.connect (() => {
if (menu_button.active) {
unowned var active_path = Scratch.Services.GitManager.get_instance ().active_project_path;
foreach (var child in project_listbox.get_children ()) {
var project_row = ((ProjectRow) child);
// All paths must not end in directory separator so can be compared directly
project_row.is_active_project = active_path == project_row.project_path;
}
}
});
update_active_project (); // Needed to update the menubutton label
}

git_manager.notify["active-project-path"].connect (update_button);
update_button ();
private bool filter_func (Scratch.FolderManager.ProjectFolderItem project) {
var project_name = Path.get_basename (project.path);
//Both are lowercased so that the case doesn't matter when comparing.
return project_name.down ().contains (project_filter.text.down ().strip ());
}

// Set appearance (only) of project chooser button and list according to active path
private void update_button () {
unowned var active_path = Scratch.Services.GitManager.get_instance ().active_project_path;
private void update_active_project () {
unowned var active_path = git_manager.active_project_path;
if (active_path != "") {
label_widget.label = Path.get_basename (active_path);
tooltip_text = _(PROJECT_TOOLTIP).printf (Scratch.Utils.replace_home_with_tilde (active_path));
} else {
label_widget.label = Path.get_basename (_(NO_PROJECT_SELECTED));
tooltip_text = _(PROJECT_TOOLTIP).printf (_(NO_PROJECT_SELECTED));
}
}

private Gtk.Widget create_project_row (Scratch.FolderManager.ProjectFolderItem project_folder) {
var project_path = project_folder.file.file.get_path ();
var project_row = new ProjectRow (project_path);
// Project folder items cannot be renamed in UI, no need to handle

return project_row;
var index = 0;
var project_row = project_listbox.get_row_at_index (index);
while (project_row != null) {
((ProjectRow) project_row).update_active (active_path);
project_row = project_listbox.get_row_at_index (++index);
}
}

public class ProjectRow : Gtk.ListBoxRow {
private Gtk.CheckButton check_button;
public bool is_active_project {
get {
return check_button.active;
}

set {
check_button.active = value;
}
}

public string project_path { get; construct; }
public string project_name {
get {
return check_button.label;
}
}
private Gtk.CheckButton check_button;
private Gtk.GestureMultiPress button_controller;

public ProjectRow (string project_path) {
Object (
project_path: project_path
);
}

private Gtk.GestureMultiPress button_controller;

class construct {
set_css_name (Gtk.STYLE_CLASS_MENUITEM);
}

construct {
can_focus = true;
activatable = true;
action_name = Scratch.MainWindow.ACTION_PREFIX + Scratch.MainWindow.ACTION_SET_ACTIVE_PROJECT;
action_target = new Variant.string (project_path);

Expand All @@ -206,10 +170,15 @@ public class Code.ChooseProjectButton : Gtk.Bin {
button = 0
};
button_controller.released.connect (() => {
activate ();
activate (); // This activates the *action* (no "row-activated" signal sent)
});

show_all ();
}

public void update_active (string active_path) {
check_button.active = active_path == project_path;
warning ("update active path %s - active %s", active_path, check_button.active.to_string ());
}
}
}

AltStyle によって変換されたページ (->オリジナル) /