Skip to content
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

[Native] Implement the macOS/Cocoa and Gtk File Dialogs #656

Merged
merged 20 commits into from
Dec 6, 2019
Merged
Changes from 4 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
24 changes: 15 additions & 9 deletions examples/Examples.re
Original file line number Diff line number Diff line change
@@ -70,7 +70,11 @@ let state: state = {
render: _ => Stopwatch.render(),
source: "Stopwatch.re",
},
{name: "Native", render: w => Native.render(w), source: "Native.re"},
{
name: "Native",
render: w => NativeExample.render(w),
source: "NativeExample.re",
},
{
name: "Input",
render: _ => InputExample.render(),
@@ -194,15 +198,17 @@ module ExampleHost = {
<ExampleButton
isActive
name={x.name}
onClick={_ => {
Window.setTitle(win, "Revery Example - " ++ x.name);
onClick={
_ => {
Window.setTitle(win, "Revery Example - " ++ x.name);

let sourceFile = getSourceForSample(state, x.name);
prerr_endline("SOURCE FILE: " ++ sourceFile);
notifyExampleSwitched(sourceFile);
dispatch(SelectExample(x.name));
();
}}
let sourceFile = getSourceForSample(state, x.name);
prerr_endline("SOURCE FILE: " ++ sourceFile);
notifyExampleSwitched(sourceFile);
dispatch(SelectExample(x.name));
();
}
}
/>;
};

28 changes: 0 additions & 28 deletions examples/Native.re

This file was deleted.

67 changes: 67 additions & 0 deletions examples/NativeExample.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
open Revery;
open Revery.UI;
open Revery.UI.Components;
open Revery.Platform;

open Revery.Native;

module NativeExamples = {
let%component make = () => {
let%hook (fileListOpt, setFileListOpt) = Hooks.state(None);

let openFile = () => {
let o = Revery.Native.Dialog.openFiles("Hello, world");
switch (o) {
| Some(a) =>
Array.iter(
x => {
Console.log("WORKS:");
Console.log(x);
Console.log("CRASHES:");
Console.log("" ++ x);
},
a,
)
| None => ()
};
setFileListOpt(_ => o);
};

let renderFilePath = (path: string) =>
<Text
style=Style.[
color(Colors.white),
fontFamily("Roboto-Regular.ttf"),
fontSize(12),
]
text=path
/>;

let containerStyle =
Style.[
position(`Absolute),
justifyContent(`Center),
alignItems(`Center),
bottom(0),
top(0),
left(0),
right(0),
];

<View style=containerStyle>
<Button title="Open File" onClick=openFile />
{
switch (fileListOpt) {
| Some(fileList) =>
fileList
|> Array.map(renderFilePath)
|> Array.to_list
|> React.listToElement
| None => <View />
}
}
</View>;
};
};

let render = window => <NativeExamples />;
8 changes: 5 additions & 3 deletions src/Native/Dialog.re
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//open Reglfw.Glfw;

[@noalloc] external alertSupported: unit => bool = "revery_alertSupported";

// [@noalloc] external alert: (NativeWindow.t, string) => unit = "revery_alert";
[@noalloc]
external openFiles:
(~startDirectory: string=?, ~fileTypes: list(string)=?, string) =>
option(array(string)) =
"revery_alertOpenFiles";
3 changes: 2 additions & 1 deletion src/Native/ReveryCocoa.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
extern "C" {
extern "C" {
void revery_alert_cocoa(void* pWin, const char* szMessage);
char** revery_open_files_cocoa(const char* startDir, char* fileTypes[], const char* title);
}
52 changes: 52 additions & 0 deletions src/Native/dialog.cpp
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@
#include <caml/callback.h>
#include <caml/memory.h>
#include <caml/mlvalues.h>
#include <string.h>


#ifdef WIN32
#include "ReveryWin32.h"
@@ -13,6 +15,17 @@
#include "ReveryGtk.h"
#endif

#define Val_none Val_int(0)
static value Val_some(value v) {
CAMLparam1(v);
CAMLlocal1(some);
some = caml_alloc(1, 0);
Store_field(some, 0, v);
CAMLreturn(some);
}

#define Some_val(v) Field(v,0)

extern "C" {
CAMLprim value revery_alertSupported() {
#ifdef WIN32
@@ -42,4 +55,43 @@ CAMLprim value revery_alert(value vWindow, value vMessage) {
#endif
return Val_unit;
}

CAMLprim value revery_alertOpenFiles(value vStartDirectory, value vFileTypes, value vTitle) {
CAMLparam3(vStartDirectory, vFileTypes, vTitle);

char *startDirectory = NULL;

char *title = String_val(vTitle);

if (vStartDirectory != Val_none) {
startDirectory = String_val(Some_val(vStartDirectory));
}
char** fileList;
#ifdef __APPLE__
fileList = revery_open_files_cocoa(startDirectory, NULL, title);
#endif

if (fileList) {
CAMLlocal2(camlArr, mlData);

int len = sizeof(fileList) / sizeof(char*);

camlArr = caml_alloc(len, 0);


for (int i = 0; i < len; i++) {
int strl = strlen(fileList[i]);

mlData = caml_alloc_string(strl);

memcpy(String_val(mlData), fileList[i], strl);

Store_field(camlArr, i, mlData);
}

CAMLreturn(Val_some(camlArr));
} else {
CAMLreturn(Val_none);
}
}
}
36 changes: 36 additions & 0 deletions src/Native/dialog_cocoa.c
Original file line number Diff line number Diff line change
@@ -14,4 +14,40 @@ void revery_alert_cocoa(void *pWin, const char *szMessage) {
[alert setInformativeText:message];
[alert runModal];
}

const char** revery_open_files_cocoa(const char *startDir, char *fileTypes[], const char *title) {
NSArray *nsFileTypes = NULL;
if (fileTypes) {
int count = 0;
while (fileTypes[count] != NULL) count++;
NSMutableArray *tmpArr = [[NSMutableArray alloc] initWithCapacity: count];
for (int i = 0; i < count; i++) {
[tmpArr addObject: [NSString stringWithCString: fileTypes[i] encoding: NSUTF8StringEncoding]];
}
nsFileTypes = tmpArr;
}
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:false];
[panel setFloatingPanel:YES];
if (startDir) {
NSString *urlString = [NSString stringWithCString: startDir encoding: NSUTF8StringEncoding];
NSLog(urlString);
NSURL *url = [NSURL fileURLWithPath: urlString];
[panel setDirectoryURL:url];
}
NSInteger result = [panel runModal];

if (result == NSModalResponseOK) {
NSArray *urls = [panel URLs];
int size = [urls count];
const char *ret[size];
for (int i = 0; i < size; i++) {
NSString *tmp = [[urls objectAtIndex:i] path];
ret[i] = [tmp UTF8String];
}
return ret;
} else {
return NULL;
}
}
#endif
2 changes: 2 additions & 0 deletions src/Revery.re
Original file line number Diff line number Diff line change
@@ -12,6 +12,8 @@ module Draw = Revery_Draw;
module Geometry = Revery_Geometry;
module Math = Revery_Math;
module Shaders = Revery_Shaders;
module Native = Revery_Native;

module UI = {
include Revery_UI;
include Revery_UI_Primitives;