[gnome-robots] Rewrite GamesFileList in Vala
- From: Andrey Kutejko <akutejko src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-robots] Rewrite GamesFileList in Vala
- Date: Tue, 6 Oct 2020 19:31:40 +0000 (UTC)
commit a6ff58dd1b2081f2d1283329f94ba68ae2fd44e7
Author: Andrey Kutejko <andy128k gmail com>
Date: Sun Aug 23 15:51:30 2020 +0200
Rewrite GamesFileList in Vala
src/file-list.vala | 237 +++++++++++++++++++++++++++
src/find-file.c | 2 +-
src/games-file-list.c | 394 ---------------------------------------------
src/games-file-list.h | 65 --------
src/image-suffix-list.vala | 16 +-
src/meson.build | 4 +-
src/properties.c | 26 +--
7 files changed, 266 insertions(+), 478 deletions(-)
---
diff --git a/src/file-list.vala b/src/file-list.vala
new file mode 100644
index 0000000..cc8d682
--- /dev/null
+++ b/src/file-list.vala
@@ -0,0 +1,237 @@
+/* games-file-list.vala:
+ Copyright 2003 Callum McKenzie
+
+ This library is free software; you can redistribute it and'or modify
+ it under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; if not, see <http://www.gnu.org/licenses/>. */
+
+/* Authors: Callum McKenzie <callum physics otago ac nz> */
+
+using Gtk;
+using Gee;
+
+public class GamesFileList {
+
+ [Flags]
+ public enum Flags {
+ REMOVE_EXTENSION = 1 << 0,
+ REPLACE_UNDERSCORES = 1 << 1,
+ }
+
+ private TreeSet<string> files;
+
+ /**
+ * @glob: A pattern to match files against. See g_pattern_spec_new () for
+ * details.
+ * @varargs: A NULL terminated list of strings containing directory names to
+ * be searched for files.
+ *
+ * This function takes a glob and a NULL terminated list of directories
+ * and constructs a list of all files in the directories that match the glob.
+ * Only regular files are returned.
+ *
+ * Return value: A pointer to a new FileList containing files
+ * matching the glob in the path.
+ **/
+ public GamesFileList (string glob, ...) {
+ var paths = va_list();
+ files = new_internal (glob, paths);
+ }
+
+ /**
+ * @path1: A NULL-terminated list of strings containing directories to be
+ * searched.
+ *
+ * A convenience function which constructs a list of filenames which
+ * are images that can be loaded via gdk-pixbuf. Whether a file is an
+ * image or not is determined by its extension. The list of possible
+ * extensions is determined by querying the gdk-pixbuf library the
+ * first time this function is called.
+ *
+ * Return value: A new FileList containing the list of image files.
+ **/
+ public GamesFileList.images (string path1, ...) {
+ files = new TreeSet<string> ();
+
+ find_images (path1, files);
+
+ var paths = va_list();
+ for (string? pathentry = paths.arg<string?> (); pathentry != null ; pathentry = paths.arg<string?>
()) {
+ find_images (pathentry, files);
+ }
+ }
+
+ /* Transform the list of files to be only the basenames. */
+ public void transform_basename () {
+ var new_files = new TreeSet<string> ();
+ foreach (var file in files) {
+ new_files.add (Path.get_basename (file));
+ }
+ files = new_files;
+ }
+
+ /**
+ * Get the number of elements in the file list.
+ **/
+ public uint length () {
+ return files.size;
+ }
+
+ /**
+ * @function: (scope call): The function to call on each item. It gets called with two
+ * arguments: the file name and the pointer supplied to this function in
+ * the userdata argument.
+ * @userdata: (closure): An arbitrary pointer that gets passed as the second argument
+ * to each call of function.
+ *
+ * Apply a function to each file name in the list.
+ **/
+ //public void @foreach (Func<string> func) {
+ // files.@foreach (func);
+ //}
+
+ /**
+ * @function: (scope call): The function to call on each item. It gets called with two
+ * arguments: the file name and the pointer supplied to this function in
+ * the userdata argument.
+ * @userdata: (closure): An arbitrary pointer that gets passed as the second argument
+ * to each call of function.
+ *
+ * Find a file name by iterating through a list until the given function
+ * returns 0.
+ *
+ * Return value: A newly allocated string containing a copy of the file name,
+ * or NULL if no file name was found.
+ **/
+ public string? find (CompareFunc<string> function, string val) {
+ return files.first_match ((file) => function (file, val) == 0);
+ }
+
+ /**
+ * @n: The 0-based index into the list.
+ *
+ * Obtain the (n+1)th file name from the list.
+ **/
+ //public string get_nth (int n) {
+ // return files[n];
+ //}
+
+ public TreeModel create_model (Flags flags) {
+ var model = new Gtk.ListStore (2, Type.STRING, Type.STRING);
+ foreach (var item in files) {
+ var visible = item;
+
+ /* These are a bit hackish, but we don't yet have a good regexp
+ * library in glib. There are probably some ways these could
+ * seriously mangle unicode strings. */
+ if (Flags.REMOVE_EXTENSION in flags) {
+ var s = visible.last_index_of (".");
+ if (s >= 0)
+ visible = visible.substring (0, s);
+ }
+ if (Flags.REPLACE_UNDERSCORES in flags) {
+ visible = visible.replace ("_", " ");
+ }
+
+ TreeIter iter;
+ model.append (out iter);
+
+ model.set_value (iter, 0, visible);
+ model.set_value (iter, 1, item);
+ }
+ return model;
+ }
+
+ /**
+ * @selection: The name to select as the default. NULL means no default.
+ * @flags: A set of flags to specify how the names are displayed.
+ *
+ * Create a combo box with the given list of strings as the entries. If
+ * selection is non-NULL the matching file name is selected by default.
+ * Otherwise nothing is selected. The flags affect how the names are
+ * displayed. The valid flags are GAMES_FILE_LIST_REMOVE_EXTENSION, which
+ * removes extensions, and GAMES_FILE_LIST_REPLACE_UNDERSCORES with replaces
+ * underscores with spaces.
+ *
+ * Return value: A widget with the list of names.
+ **/
+ public Widget create_widget (string? selection, Flags flags) {
+ var model = create_model (flags);
+ var widget = new ComboBox.with_model (model);
+ var renderer = new CellRendererText ();
+ widget.pack_start (renderer, true);
+ widget.add_attribute (renderer, "text", 0);
+
+ bool found = false;
+ if (selection != null) {
+ TreeIter iter;
+ if (model.get_iter_first (out iter)) {
+ do {
+ Value file;
+ model.get_value (iter, 1, out file);
+ if (file == selection) {
+ widget.set_active_iter (iter);
+ found = true;
+ break;
+ }
+ } while (model.iter_next (ref iter));
+ }
+ }
+ if (!found) {
+ widget.set_active (0);
+ }
+
+ return widget;
+ }
+
+ private static TreeSet<string> new_internal (string glob, va_list paths) {
+ var result = new TreeSet<string> ();
+ var filespec = new PatternSpec (glob);
+
+ for (string? pathelement = paths.arg<string?> (); pathelement != null ; pathelement =
paths.arg<string?> ()) {
+ try {
+ var dir = Dir.open (pathelement);
+ string? filename;
+ while ((filename = dir.read_name ()) != null) {
+ if (filespec.match_string (filename)) {
+ var fullname = Path.build_filename (pathelement, filename);
+ if (FileUtils.test (fullname, FileTest.IS_REGULAR)) {
+ result.add (fullname);
+ }
+ }
+ }
+ } catch (FileError e) {
+ // ignored
+ }
+ }
+
+ return result;
+ }
+
+ private static void find_images (string directory, TreeSet<string> result) {
+ try {
+ var dir = Dir.open (directory);
+ string? filename;
+ while ((filename = dir.read_name ()) != null) {
+ if (ImageSuffixList.has_image_suffix (filename)) {
+ var fullname = Path.build_filename (directory, filename);
+ if (FileUtils.test (fullname, FileTest.IS_REGULAR)) {
+ result.add (fullname);
+ }
+ }
+ }
+ } catch (FileError e) {
+ // ignored
+ }
+ }
+}
+
diff --git a/src/find-file.c b/src/find-file.c
index eda3c3b..1c8fc50 100644
--- a/src/find-file.c
+++ b/src/find-file.c
@@ -23,7 +23,7 @@
#include <glib.h>
#include "find-file.h"
-#include "games-file-list.h"
+#include "riiv.h"
static gchar *
make_canonical_name (const gchar * name)
diff --git a/src/image-suffix-list.vala b/src/image-suffix-list.vala
index e898b38..b6b22cb 100644
--- a/src/image-suffix-list.vala
+++ b/src/image-suffix-list.vala
@@ -15,24 +15,24 @@
You should have received a copy of the GNU Library General Public License
along with this library; if not, see <http://www.gnu.org/licenses/>. */
+using Gee;
using Gdk;
namespace ImageSuffixList
{
- private static SList<string> list = null;
+ private static ArrayList<string> list = null;
private static Mutex mutex;
- public unowned SList<string> get()
- {
+ public unowned ArrayList<string> get() {
mutex.lock ();
- if (list == null)
- {
+ if (list == null) {
+ list = new ArrayList<string> ();
Pixbuf.get_formats ().@foreach ((formats) => {
var suffices = formats.get_extensions ();
foreach (var suffix in suffices) {
- list.append (".%s".printf (suffix));
+ list.add (".%s".printf (suffix));
}
});
}
@@ -41,4 +41,8 @@ namespace ImageSuffixList
return list;
}
+
+ public bool has_image_suffix (string filename) {
+ return get ().any_match ((suffix) => filename.has_suffix (suffix));
+ }
}
diff --git a/src/meson.build b/src/meson.build
index aebd553..0e5f21f 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,5 +1,6 @@
vala_sources = files(
- 'image-suffix-list.vala'
+ 'image-suffix-list.vala',
+ 'file-list.vala',
)
vala_lib = static_library('riiv',
@@ -26,7 +27,6 @@ sources = files(
'game.c',
'gameconfig.c',
'games-controls.c',
- 'games-file-list.c',
'games-preimage.c',
'gnome-robots.c',
'graphics.c',
diff --git a/src/properties.c b/src/properties.c
index d389c5e..fc15f49 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -34,7 +34,7 @@
#include "gbdefs.h"
#include "keyboard.h"
#include "game.h"
-#include "games-file-list.h"
+#include "riiv.h"
#include "games-controls.h"
@@ -173,17 +173,23 @@ delete_cb (GtkWidget * w, gpointer data)
static void
pmap_selection (GtkWidget * widget, gpointer data)
{
- gint n;
+ GtkTreeIter iter;
- n = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) {
+ GtkTreeModel *model;
+ GValue value = G_VALUE_INIT;
- /* FIXME: Should be de-suffixed. */
- properties.themename = games_file_list_get_nth (theme_list, n);
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+ gtk_tree_model_get_value (model, &iter, 1, &value);
- conf_set_theme (properties.themename);
+ /* FIXME: Should be de-suffixed. */
+ properties.themename = g_value_get_string (&value);
- load_game_graphics ();
- clear_game_area ();
+ conf_set_theme (properties.themename);
+
+ load_game_graphics ();
+ clear_game_area ();
+ }
}
@@ -340,8 +346,8 @@ make_theme_menu (void)
return games_file_list_create_widget (theme_list,
properties.themename,
- GAMES_FILE_LIST_REMOVE_EXTENSION |
- GAMES_FILE_LIST_REPLACE_UNDERSCORES);
+ GAMES_FILE_LIST_FLAGS_REMOVE_EXTENSION |
+ GAMES_FILE_LIST_FLAGS_REPLACE_UNDERSCORES);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]