Преглед на файлове

added cross-platform file dialog

Former-commit-id: 206be9611e92e8b0921f339d985ffdbf4b92677e
Daniele Panozzo преди 11 години
родител
ревизия
e5a4f25bbb
променени са 2 файла, в които са добавени 187 реда и са изтрити 0 реда
  1. 143 0
      include/igl/file_dialog.cpp
  2. 44 0
      include/igl/file_dialog.h

+ 143 - 0
include/igl/file_dialog.cpp

@@ -0,0 +1,143 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+
+#define FILE_DIALOG_MAX_BUFFER 1024
+
+std::string IGL_INLINE igl::file_dialog_open()
+{
+  char buffer[FILE_DIALOG_MAX_BUFFER];
+  
+#ifdef __APPLE__
+  // For apple use applescript hack
+  FILE * output = popen(
+                        "osascript -e \""
+                        "   tell application \\\"System Events\\\"\n"
+                        "           activate\n"
+                        "           set existing_file to choose file\n"
+                        "   end tell\n"
+                        "   set existing_file_path to (POSIX path of (existing_file))\n"
+                        "\" 2>/dev/null | tr -d '\n' ","r");
+  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){
+  }
+#elif _WIN32
+  
+  // Use native windows file dialog box
+  // (code contributed by Tino Weinkauf)
+
+  OPENFILENAME ofn;       // common dialog box structure
+  char szFile[260];       // buffer for file name
+  HWND hwnd;              // owner window
+  HANDLE hf;              // file handle
+
+  // Initialize OPENFILENAME
+  ZeroMemory(&ofn, sizeof(ofn));
+  ofn.lStructSize = sizeof(ofn);
+  ofn.hwndOwner = NULL;//hwnd;
+  ofn.lpstrFile = new wchar_t[100];
+  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
+  // use the contents of szFile to initialize itself.
+  ofn.lpstrFile[0] = '\0';
+  ofn.nMaxFile = sizeof(szFile);
+  ofn.lpstrFilter = L"*.*\0";//off\0*.off\0obj\0*.obj\0mp\0*.mp\0";
+  ofn.nFilterIndex = 1;
+  ofn.lpstrFileTitle = NULL;
+  ofn.nMaxFileTitle = 0;
+  ofn.lpstrInitialDir = NULL;
+  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+  // Display the Open dialog box. 
+  int pos = 0;
+  if (GetOpenFileName(&ofn)==TRUE)
+  {
+    while(ofn.lpstrFile[pos] != '\0')
+    {
+      buffer[pos] = (char)ofn.lpstrFile[pos];
+      pos++;
+    }
+    buffer[pos] = 0;
+  } 
+  
+#else
+  
+  // For linux use zenity
+  FILE * output = popen("/usr/bin/zenity --file-selection","r");
+  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){
+  }
+  
+  if (strlen(buffer) > 0)
+    buffer[strlen(buffer)-1] = 0;
+#endif
+  return std::string(buffer);
+}
+
+std::string IGL_INLINE igl::file_dialog_save()
+{
+  char buffer[FILE_DIALOG_MAX_BUFFER];
+#ifdef __APPLE__
+  // For apple use applescript hack
+  // There is currently a bug in Applescript that strips extensions off
+  // of chosen existing files in the "choose file name" dialog
+  // I'm assuming that will be fixed soon
+  FILE * output = popen(
+                        "osascript -e \""
+                        "   tell application \\\"System Events\\\"\n"
+                        "           activate\n"
+                        "           set existing_file to choose file name\n"
+                        "   end tell\n"
+                        "   set existing_file_path to (POSIX path of (existing_file))\n"
+                        "\" 2>/dev/null | tr -d '\n' ","r");
+  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){
+  }
+#elif _WIN32
+
+  // Use native windows file dialog box
+  // (code contributed by Tino Weinkauf)
+
+  OPENFILENAME ofn;       // common dialog box structure
+  char szFile[260];       // buffer for file name
+  HWND hwnd;              // owner window
+  HANDLE hf;              // file handle
+
+  // Initialize OPENFILENAME
+  ZeroMemory(&ofn, sizeof(ofn));
+  ofn.lStructSize = sizeof(ofn);
+  ofn.hwndOwner = NULL;//hwnd;
+  ofn.lpstrFile = new wchar_t[100];
+  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
+  // use the contents of szFile to initialize itself.
+  ofn.lpstrFile[0] = '\0';
+  ofn.nMaxFile = sizeof(szFile);
+  ofn.lpstrFilter = L"";
+  ofn.nFilterIndex = 1;
+  ofn.lpstrFileTitle = NULL;
+  ofn.nMaxFileTitle = 0;
+  ofn.lpstrInitialDir = NULL;
+  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+  // Display the Open dialog box. 
+  int pos = 0;
+  if (GetSaveFileName(&ofn)==TRUE)
+  {
+    while(ofn.lpstrFile[pos] != '\0')
+    {
+      buffer[pos] = (char)ofn.lpstrFile[pos];
+      pos++;
+    }
+    buffer[pos] = 0;
+  }
+
+#else
+  // For every other machine type use zenity
+  FILE * output = popen("/usr/bin/zenity --file-selection --save","r");
+  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){
+  }
+  
+  if (strlen(buffer) > 0)
+    buffer[strlen(buffer)-1] = 0;
+#endif
+}

+ 44 - 0
include/igl/file_dialog.h

@@ -0,0 +1,44 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+#ifndef IGL_FILE_DIALOG_H
+#define IGL_FILE_DIALOG_H
+
+#include <stdio.h>
+#include <string>
+
+#ifdef _WIN32
+ #include <Commdlg.h>
+#endif
+
+namespace igl
+{
+
+// Returns a string with a path to an existing file
+// The string is returned empty if no file is selected
+// (on Linux machines, it assumes that Zenity is installed)
+//
+// Usage:
+//   std::string str = get_open_file_path();
+std::string IGL_INLINE file_dialog_open();
+
+// Returns a string with a path to a new/existing file
+// The string is returned empty if no file is selected
+// (on Linux machines, it assumes that Zenity is installed)
+//
+// Usage:
+//   char buffer[FILE_DIALOG_MAX_BUFFER];
+//   get_save_file_path(buffer);
+std::string IGL_INLINE file_dialog_save();
+
+}
+
+#ifdef IGL_HEADER_ONLY
+#  include "file_dialog.cpp"
+#endif
+
+#endif