diff --git a/meson.build b/meson.build index 82683106..2d592834 100644 --- a/meson.build +++ b/meson.build @@ -45,6 +45,7 @@ json_glib_dep = dependency('json-glib-1.0') switchboard_dep = dependency('switchboard-3') libhandy_dep = dependency('libhandy-1', version: '>= 0.83.0') wingpanel_dep = dependency('wingpanel', version: '>=2.1.0') +math_dep = meson.get_compiler('c').find_library('m') posix_dep = meson.get_compiler('vala').find_library('posix') zeitgeist_dep = [] diff --git a/src/Views/GridView.vala b/src/Views/GridView.vala index f6eca483..6929992d 100644 --- a/src/Views/GridView.vala +++ b/src/Views/GridView.vala @@ -7,6 +7,7 @@ public class Slingshot.Widgets.Grid : Gtk.Box { private const int PAGE_ROWS = 3; private const int PAGE_COLUMNS = 5; + private const int MAX_APPS_IN_PAGE = (PAGE_ROWS * PAGE_COLUMNS); private Hdy.Carousel paginator; private Gtk.EventControllerKey key_controller; @@ -75,28 +76,22 @@ public class Slingshot.Widgets.Grid : Gtk.Box { paginator.remove (child); } - var grid = add_new_grid (); - // Where to insert new app button - var next_row_index = 0; - var next_col_index = 0; + var apps = app_system.get_apps_by_name (); + var num_apps = apps.length (); - foreach (Backend.App app in app_system.get_apps_by_name ()) { - var app_button = new Widgets.AppButton (app); - app_button.app_launched.connect (() => ((Gtk.Popover) get_ancestor (typeof (Gtk.Popover))).popdown ()); + // e.g. Number of pages needed to show 33 apps is 3; 2 pages with fully apps and 1 additional page + var num_pages = (int) Math.ceil ((double) num_apps / MAX_APPS_IN_PAGE); - if (next_col_index == PAGE_COLUMNS) { - next_col_index = 0; - next_row_index++; - } + for (uint page_idx = 0; page_idx < num_pages; page_idx++) { + // Number of total apps populated after dealing with this page + // clamp is used to handle last page correctly; has no effect for other pages + var num_apps_populated = ((page_idx + 1) * MAX_APPS_IN_PAGE).clamp (1, num_apps); - if (next_row_index == PAGE_ROWS) { - grid = add_new_grid (); - next_row_index = 0; - next_col_index = 0; - } + // Number of apps in this page, in range of 1 to MAX_APPS_IN_PAGE + // Subtract 1 before calculating modulo and finally adds 1 to prevent the result becomes 0 + var num_apps_in_page = ((num_apps_populated - 1) % MAX_APPS_IN_PAGE) + 1; - grid.attach (app_button, (int)next_col_index, (int)next_row_index); - next_col_index++; + populate_page (apps.nth (page_idx * MAX_APPS_IN_PAGE), num_apps_in_page); } show_all (); @@ -104,6 +99,31 @@ public class Slingshot.Widgets.Grid : Gtk.Box { set_page (0); } + private void populate_page (SList apps, uint num_apps) { + var grid = add_new_grid (); + + for (var row = 0; row < PAGE_ROWS; row++) { + for (var column = 0; column < PAGE_COLUMNS; column++) { + Gtk.Widget widget_to_attach; + + var app_idx = (row * PAGE_COLUMNS) + column; + if (app_idx < num_apps) { + unowned var app = apps.nth_data (app_idx); + + var app_button = new Widgets.AppButton (app); + app_button.app_launched.connect (() => ((Gtk.Popover) get_ancestor (typeof (Gtk.Popover))).popdown ()); + + widget_to_attach = app_button; + } else { + // Fake grid in case there are not enough apps to fill the page + widget_to_attach = new Gtk.Grid (); + } + + grid.attach (widget_to_attach, column, row); + } + } + } + private Gtk.Grid add_new_grid () { var grid = new Gtk.Grid () { hexpand = true, @@ -116,13 +136,6 @@ public class Slingshot.Widgets.Grid : Gtk.Box { column_spacing = 0 }; - // Fake grids in case there are not enough apps to fill the grid - for (var row = 0; row < PAGE_ROWS; row++) { - for (var column = 0; column < PAGE_COLUMNS; column++) { - grid.attach (new Gtk.Grid (), column, row, 1, 1); - } - } - paginator.add (grid); return grid; diff --git a/src/meson.build b/src/meson.build index e913d34e..8c42d1d2 100644 --- a/src/meson.build +++ b/src/meson.build @@ -82,6 +82,7 @@ dependencies = [ zeitgeist_dep, wingpanel_dep, libhandy_dep, + math_dep, posix_dep, ]