Skip to content

Commit

Permalink
[feat] FFI: add FileChooser Gtk3 backend (#631)
Browse files Browse the repository at this point in the history
  • Loading branch information
Frenzie committed Apr 3, 2018
1 parent 7833bf1 commit 18cac08
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
14 changes: 14 additions & 0 deletions ffi/filechooser.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
local ffi = require("ffi")
local util = require("ffi/util")

if util.isSDL() then
if util.haveSDL2() then
local ok, gtk = pcall(ffi.load, "gtk-3")
if not ok then
ok, gtk = pcall(ffi.load, "gtk-3.so.0")
end
if ok then
return require("ffi/filechooser_gtk-3")
end
end
end
56 changes: 56 additions & 0 deletions ffi/filechooser_gtk-3.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
local ffi = require "ffi"

local dummy = require("ffi/gtk-3_h")

local ok, gtk = pcall(ffi.load, "gtk-3")
if not ok then
ok, gtk = pcall(ffi.load, "gtk-3.so.0")
end
if not ok then return end

local FileChooser = {
type = "gtk-3",
}

--[[
Mostly taken from https://love2d.org/forums/viewtopic.php?f=4&t=82442
Proof of concept, https://github.com/Alloyed/nativefiledialog might be better.
--]]

function FileChooser:show(action, button, title)
gtk.gtk_init(nil, nil)

local d = gtk.gtk_file_chooser_dialog_new(
title,
nil,
action,
"_Cancel", ffi.cast("const gchar *", gtk.GTK_RESPONSE_CANCEL),
button, ffi.cast("const gchar *", gtk.GTK_RESPONSE_OK),
nil)

local response = gtk.gtk_dialog_run(d)
local filename = gtk.gtk_file_chooser_get_filename(d)

gtk.gtk_widget_destroy(d)

while gtk.gtk_events_pending() do
gtk.gtk_main_iteration()
end

if response == gtk.GTK_RESPONSE_OK then
return filename ~= nil and ffi.string(filename) or nil
end
end

function FileChooser:save(title)
return self:show(gtk.GTK_FILE_CHOOSER_ACTION_SAVE,
"_Save", title or "Save As")
end

function FileChooser:open(title)
return self:show(gtk.GTK_FILE_CHOOSER_ACTION_OPEN,
"_Open", title or "Open")
end

return FileChooser
70 changes: 70 additions & 0 deletions ffi/gtk-3_h.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
local ffi = require "ffi"

ffi.cdef [[

typedef void GtkDialog;
typedef void GtkWidget;
typedef void GtkWindow;
typedef void GtkFileChooser;

typedef int gint;
typedef char gchar;
typedef bool gboolean;

typedef enum
{
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
} GtkFileChooserAction;

typedef enum
{
GTK_RESPONSE_NONE = -1,
GTK_RESPONSE_REJECT = -2,
GTK_RESPONSE_ACCEPT = -3,
GTK_RESPONSE_DELETE_EVENT = -4,
GTK_RESPONSE_OK = -5,
GTK_RESPONSE_CANCEL = -6,
GTK_RESPONSE_CLOSE = -7,
GTK_RESPONSE_YES = -8,
GTK_RESPONSE_NO = -9,
GTK_RESPONSE_APPLY = -10,
GTK_RESPONSE_HELP = -11
} GtkResponseType;

void gtk_init (
int *argc,
char ***argv
);

gboolean gtk_events_pending (
void
);

gboolean gtk_main_iteration (
void
);

GtkWidget * gtk_file_chooser_dialog_new (
const gchar *title,
GtkWindow *parent,
GtkFileChooserAction action,
const gchar *first_button_text,
...
);

gint gtk_dialog_run (
GtkDialog *dialog
);

void gtk_widget_destroy (
GtkWidget *widget
);

gchar * gtk_file_chooser_get_filename (
GtkFileChooser *chooser
);

]]
2 changes: 2 additions & 0 deletions ffi/input_SDL2_0.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local FileChooser = require("ffi/filechooser")
-- load common SDL input/video library
local SDL = require("ffi/SDL2_0")

Expand All @@ -11,4 +12,5 @@ return {
hasClipboardText = SDL.hasClipboardText,
getClipboardText = SDL.getClipboardText,
setClipboardText = SDL.setClipboardText,
file_chooser = FileChooser,
}

0 comments on commit 18cac08

Please sign in to comment.