Repository: lutris/lutris

Issue:
Add option to turn columns on/off in List View
When right-clicking to table headbar in List View, you expect to get a menu for turning columns on/off, but you just select first game in the list.


Discussion:
Yeah, if you right click on "Name" here the menu for the first game gets opened, which is a bit weird:
![image](https://user-images.githubusercontent.com/10602045/71997869-a200fb80-324f-11ea-9ac4-be8663d44c35.png)

2 very different issues.
The initial report is a feature request (and, no. You shouldn't expect columns to be hidden / shown on right click, this is in no way universal)
The other is an actual bug.

Going to fix the right click on header bar issue independently of this ticket and move that one for a later release.
Tried to change the behavior related to the 1st row being select when right clicking the headers but didn't find a solution

Resolving patch:
diff --git a/lutris/gui/views/list.py b/lutris/gui/views/list.py
--- a/lutris/gui/views/list.py
+++ b/lutris/gui/views/list.py
@@ -39,7 +39,7 @@ def __init__(self, store):
         name_cell = self.set_text_cell()
         name_cell.set_padding(5, 0)
 
-        self.set_column(name_cell, _("Name"), COL_NAME, 200)
+        self.set_column(name_cell, _("Name"), COL_NAME, 200, always_visible=True)
         self.set_column(default_text_cell, _("Year"), COL_YEAR, 60)
         self.set_column(default_text_cell, _("Runner"), COL_RUNNER_HUMAN_NAME, 120)
         self.set_column(default_text_cell, _("Platform"), COL_PLATFORM, 120)
@@ -63,7 +63,7 @@ def set_text_cell():
         text_cell.set_property("ellipsize", Pango.EllipsizeMode.END)
         return text_cell
 
-    def set_column(self, cell, header, column_id, default_width, sort_id=None):
+    def set_column(self, cell, header, column_id, default_width, always_visible=False, sort_id=None):
         column = Gtk.TreeViewColumn(header, cell, markup=column_id)
         column.set_sort_indicator(True)
         column.set_sort_column_id(column_id if sort_id is None else sort_id)
@@ -71,9 +71,12 @@ def set_column(self, cell, header, column_id, default_width, sort_id=None):
         column.set_resizable(True)
         column.set_reorderable(True)
         width = settings.read_setting("%s_column_width" % COLUMN_NAMES[column_id], "list view")
+        is_visible = settings.read_setting("%s_visible" % COLUMN_NAMES[column_id], "list view")
         column.set_fixed_width(int(width) if width else default_width)
+        column.set_visible(is_visible == "True" or always_visible if is_visible else True)
         self.append_column(column)
         column.connect("notify::width", self.on_column_width_changed)
+        column.get_button().connect('button-press-event', self.on_column_header_button_pressed)
         return column
 
     def set_column_sort(self, col):
@@ -101,6 +104,13 @@ def set_selected_game(self, game_id):
         if row:
             self.set_cursor(row.path)
 
+    def on_column_header_button_pressed(self, button, event):
+        """Handles column header button press events"""
+        if event.button == 3:
+            menu = GameListColumnToggleMenu(self.get_columns())
+            menu.popup_at_pointer(None)
+            return True
+
     def on_row_activated(self, widget, line=None, column=None):
         """Handles double clicks"""
         selected_item = self.get_selected_item()
@@ -127,3 +137,37 @@ def on_column_width_changed(col, *args):
                 col.get_fixed_width(),
                 "list view",
             )
+
+
+class GameListColumnToggleMenu(Gtk.Menu):
+
+    def __init__(self, columns):
+        super().__init__()
+        self.columns = columns
+        self.column_map = {}
+        self.create_menuitems()
+        self.show_all()
+
+    def create_menuitems(self):
+        for column in self.columns:
+            title = column.get_title()
+            if title == "":
+                continue
+            checkbox = Gtk.CheckMenuItem(title)
+            checkbox.set_active(column.get_visible())
+            if title == _("Name"):
+                checkbox.set_sensitive(False)
+            else:
+                checkbox.connect("toggled", self.on_toggle_column)
+            self.column_map[checkbox] = column
+            self.append(checkbox)
+
+    def on_toggle_column(self, check_menu_item):
+        column = self.column_map[check_menu_item]
+        is_visible = check_menu_item.get_active()
+        column.set_visible(is_visible)
+        settings.write_setting(
+            column.get_title().replace(" ", "") + "_visible",
+            str(is_visible),
+            "list view",
+        )


Test patch: