Use tiny file dialogs

master
stujones11 2018-09-09 16:53:07 +01:00
parent a4de109ba1
commit 224f2d0be1
8 changed files with 2469 additions and 61 deletions

View File

@ -40,11 +40,11 @@ include_directories(
${IRRLICHT_INCLUDE_DIR}
${PROJECT_SOURCE_DIR}/src
)
file(GLOB SRCS src/*.cpp)
file(GLOB SRCS src/*.cpp src/*.c)
file(MAKE_DIRECTORY "bin")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -pthread")
add_executable(${PROJECT_NAME} ${SRCS})
target_link_libraries(${PROJECT_NAME} ${IRRLICHT_LIBRARY})

View File

@ -55,3 +55,12 @@ The Irrlicht Engine License:
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Tiny File Dialogs
-----------------
Copyright (c) 2014 - 2015 Guillaume Vareille http://ysengrin.com
http://tinyfiledialogs.sourceforge.net
tiny file dialogs - tinyfd - version 1.7.0 [January 30, 2015] zlib licence.
Cross-platform dialogs in C/C++ WINDOWS OSX GNOME KDE SOLARIS CONSOLE

View File

@ -13,17 +13,40 @@ Features
* Mesh debug view. (wire-frame, skeleton and normals)
* Animation playback amd frame controls.
Supported Formats
-----------------
Supported Mesh Formats
----------------------
Compatible with all mesh formats supported by Irrlicht engine.
* B3D files (.b3d)
* DirectX (.x)
* Alias Wavefront Maya (.obj)
* Irrlicht scenes (.irr)
* Irrlicht static meshes (.irrmesh)
* 3D Studio meshes (.3ds)
* B3D files (.b3d)
* Alias Wavefront Maya (.obj)
* Lightwave Objects (.lwo)
* COLLADA 1.4 (.xml, .dae)
* Microsoft DirectX (.x) (binary & text)
* Milkshape (.ms3d)
* OGRE meshes (.mesh)
* My3DTools 3 (.my3D)
* Pulsar LMTools (.lmts)
* Quake 3 levels (.bsp)
* Quake 2 models (.md2)
* Quake 3 models (.md3)
* DeleD (.dmf)
* FSRad oct (.oct)
* Cartography shop 4 (.csm)
* STL 3D files (.stl)
Supported Texture Formats
-------------------------
* JPEG File Interchange Format (.jpg)
* Portable Network Graphics (.png)
* Truevision Targa (.tga)
* Windows Bitmap (.bmp)
* Adobe Photoshop (.psd)
* Zsoft Paintbrush (.pcx)
* Portable Pixmaps (.ppm)
* Quake 2 textures (.wal)
Installation
------------
@ -67,7 +90,6 @@ Controls
To Do
-----
* Improve file-browser.
* Basic lighting.
* Image capture tools.

View File

@ -1,3 +1,4 @@
#include <thread>
#include <stdlib.h>
#include <iostream>
#include <irrlicht.h>
@ -5,6 +6,7 @@
#include "config.h"
#include "scene.h"
#include "dialog.h"
#include "tinyfiledialogs.h"
#ifdef USE_CMAKE_CONFIG_H
#include "cmake_config.h"
@ -14,6 +16,48 @@
#define D_VERSION "0.0"
#endif
namespace dialog
{
SEvent event;
bool has_event = false;
const char *filename = "";
void showFileOpen(IGUIEnvironment *env, s32 id, const char *caption,
const char **filters, const int filter_count)
{
IGUIWindow *window = env->addWindow(rect<s32>(0,0,0,0), true);
window->setVisible(false);
io::IFileSystem *fs = env->getFileSystem();
io::path path = fs->getWorkingDirectory() + "/";
const char *fn = tinyfd_openFileDialog(caption, path.c_str(),
filter_count, filters, 0);
try
{
event.EventType = EET_GUI_EVENT;
event.UserEvent.UserData1 = id;
if (fn)
{
filename = fn;
io::path cwd = fs->getFileDir(fn);
fs->changeWorkingDirectoryTo(cwd);
event.GUIEvent.EventType = EGET_FILE_SELECTED;
}
else
{
filename = "";
event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED;
}
window->remove();
has_event = true;
}
catch (const std::exception& except)
{
std::cout << except.what() << std::endl;
}
}
}
static inline void open_url(std::string url)
{
system((std::string("xdg-open \"") + url + std::string("\"")).c_str());
@ -400,11 +444,20 @@ ITexture *TexturesDialog::getTexture(const io::path &filename)
return texture;
}
void TexturesDialog::draw()
{
if (dialog::has_event)
{
OnEvent(dialog::event);
dialog::has_event = false;
}
IGUIElement::draw();
}
bool TexturesDialog::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
if (event.GUIEvent.Caller->getType() == EGUIET_EDIT_BOX)
@ -419,6 +472,7 @@ bool TexturesDialog::OnEvent(const SEvent &event)
}
else if (event.GUIEvent.EventType == EGET_CHECKBOX_CHANGED)
{
s32 id = event.GUIEvent.Caller->getID();
IGUICheckBox *check = (IGUICheckBox*)getElementFromId(id, true);
std::string is_checked = (check->isChecked()) ? "true" : "false";
@ -451,6 +505,7 @@ bool TexturesDialog::OnEvent(const SEvent &event)
}
else if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
{
s32 id = event.GUIEvent.Caller->getID();
if (id == E_DIALOG_ID_TEXTURES_OK)
{
IGUIEditBox *edit;
@ -483,32 +538,35 @@ bool TexturesDialog::OnEvent(const SEvent &event)
}
else
{
s32 texture_id = 0;
for (s32 i = 0; i < 6; ++i)
{
if (id == E_BUTTON_ID_MODEL + i)
{
Environment->addFileOpenDialog(L"Open Image File",
true, this, E_TEXTURE_ID_MODEL + i);
texture_id = E_TEXTURE_ID_MODEL;
break;
}
else if (id == E_BUTTON_ID_WIELD + i)
{
Environment->addFileOpenDialog(L"Open Image File",
true, this, E_TEXTURE_ID_WIELD + i);
texture_id = E_TEXTURE_ID_WIELD;
break;
}
}
if (texture_id)
{
std::thread thread(dialog::showFileOpen,
Environment, texture_id, "Open Image File",
dialog::texture_filters, dialog::texture_filter_count);
thread.detach();
}
}
}
else if (event.GUIEvent.EventType == EGET_FILE_SELECTED)
{
IGUIFileOpenDialog *dialog =
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
stringw fn = stringw(dialog->getFileName());
stringw fn = dialog::filename;
if (!fn.empty())
{
s32 id = dialog->getID();
s32 id = event.UserEvent.UserData1;
IGUIEditBox *edit = (IGUIEditBox*)getElementFromId(id, true);
if (edit)
{

View File

@ -7,6 +7,29 @@ using namespace scene;
using namespace gui;
using namespace video;
namespace dialog
{
static const int model_filter_count = 19;
static const char *model_filters[] = {
"*.obj", "*.b3d", "*.x", "*.3ds",
"*.irr", "*.irrmesh", "*.md2", "*.md3",
"*.bsp", "*.mesh", "*.ms3d", "*.my3D",
"*.lwo", "*.xml", "*.dae", "*.dmf",
"*.oct", "*.csm", "*.stl"
};
static const int texture_filter_count = 8;
static const char *texture_filters[] = {
"*.png", "*.jpg", "*.tga", "*.bmp",
"*.psd", "*.pcx", "*.ppm", "*.wal"
};
extern const char *filename;
extern bool has_event;
extern SEvent event;
void showFileOpen(IGUIEnvironment *env, s32 id, const char *caption,
const char **filters, const int filter_count);
}
enum
{
E_DIALOG_ID_ABOUT = 0x1000,
@ -99,6 +122,7 @@ public:
TexturesDialog(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, Config *conf, ISceneManager *smgr);
virtual ~TexturesDialog() {}
virtual void draw();
virtual bool OnEvent(const SEvent &event);
private:

2157
src/tinyfiledialogs.c Normal file

File diff suppressed because it is too large Load Diff

132
src/tinyfiledialogs.h Normal file
View File

@ -0,0 +1,132 @@
/*
tinyfiledialogs.h
optional unique header file of the tiny file dialogs library - tinyfd
created [November 9, 2014]
Copyright (c) 2014 - 2015 Guillaume Vareille http://ysengrin.com
http://tinyfiledialogs.sourceforge.net
tiny file dialogs - tinyfd - version 1.7.0 [January 30, 2015] zlib licence.
Cross-platform dialogs in C/C++ WINDOWS OSX GNOME KDE SOLARIS CONSOLE
Tested with C & C++ compilers
on Visual Studio 2013 OSX Linux Freebsd Illumos Solaris.
A single C file (add it to your project) with 6 modal function calls:
- open file dialog (& multiple files)
- save file dialog
- select folder dialog
- message box (& question)
- input box
- color picker.
Conceived as a fully independent complement to GLUT, GLUI, SDL, UNITY3D
or any GUI-less program, there is NO MAIN LOOP nor init.
It also provides CONSOLE dialogs on unix.
On Windows native code creates the dialogs (mostly).
On UNIX it tries successive command line calls:
- zenity
- kdialog
- applescript
- python 2 / tkinter
- dialog.
The same executable can run across desktops and distributions.
- License -
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef TINYFILEDIALOGS_H
#define TINYFILEDIALOGS_H
/*
if tinydialogs.c is compiled with a C++ compiler
rather than with a C compiler, you need to comment out:
extern "C" {
and the corresponding closing bracket:
}
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern int tinyfd_forceConsole ; /* for UNIX only: 0 (default) or 1 */
/* 1 forces all dialogs into console mode even when the X server is present */
/* can be modified at run time */
int tinyfd_messageBox (
char const * const aTitle , /* "" */
char const * const aMessage , /* "" may contain \n and \t */
char const * const aDialogType , /* "ok" "okcancel" "yesno" */
char const * const aIconType , /* "info" "warning" "error" "question" */
int const aDefaultButton ) ; /* 0 for cancel/no , 1 for ok/yes */
/* returns 0 for cancel/no , 1 for ok/yes */
char const * tinyfd_saveFileDialog (
char const * const aTitle , /* "" */
char const * const aDefaultPathAndFile , /* "" */
int const aNumOfFileFilters , /* 0 */
char const * const * const aFileFilters ) ; /* NULL or {"*.txt"} */
char const * tinyfd_openFileDialog (
char const * const aTitle , /* "" */
char const * const aDefaultPathAndFile , /* "" */
int const aNumOfFileFilters , /* 0 */
char const * const * const aFileFilters , /* NULL or {"*.jpg","*.png"} */
int aAllowMultipleSelects ) ; /* 0 or 1 */
/* in case of multiple files, the separator is | */
char const * tinyfd_selectFolderDialog (
char const * const aTitle , /* "" */
char const * const aDefaultPath ) ; /* "" */
char const * tinyfd_inputBox(
char const * const aTitle , /* "" */
char const * const aMessage , /* "" may NOT contain \n nor \t */
char const * const aDefaultInput ) ; /* "" */
/* on cancel it returns aDefaultInput */
char const * tinyfd_colorChooser(
char const * const aTitle , /* "" */
char const * const aDefaultHexRGB , /* NULL or "#FF0000" */
unsigned char aDefaultRGB[3] , /* { 0 , 255 , 255 } */
unsigned char aoResultRGB[3] ) ; /* { 0 , 0 , 0 } */
/* returns the hexcolor as a string "#FF0000" */
/* aoResultRGB also contains the result */
/* aDefaultRGB is used only if aDefaultHexRGB is NULL */
/* aDefaultRGB and aoResultRGB can be the same array */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* TINYFILEDIALOGS_H */
/*
- On linux: link against Comdlg32.lib User32.lib and Shell32.lib
- On unix: it tries command line calls, so no such need.
- Use linux separator on linux and unix separator on unix.
- char const * fileFilters[3] = { "*.obj" , "*.stl" , "*.dxf" } ;
- String memory is preallocated statically for all the returned values.
- On unix you need zenity or kdialog or python2/tkinter or dialog installed.
Don't worry, it's already included on most (if not all) desktops.
- If you pass only a path instead of path + filename,
make sure it ends with a separator.
- tinyfd_forceConsole=1; forces all dialogs into console mode (unix only).
*/

View File

@ -1,4 +1,5 @@
#include <stdlib.h>
#include <thread>
#include <iostream>
#include <sstream>
#include <irrlicht.h>
@ -80,6 +81,8 @@ bool Viewer::run(IrrlichtDevice *irr_device)
while (device->run())
{
resize();
if (dialog::has_event)
dialog::has_event = !OnEvent(dialog::event);
driver->beginScene(true, true, bg_color);
smgr->drawAll();
env->drawAll();
@ -154,16 +157,25 @@ bool Viewer::OnEvent(const SEvent &event)
s32 item = menu->getSelectedItem();
s32 id = menu->getItemCommandId(item);
IGUIEnvironment *env = device->getGUIEnvironment();
switch (id)
{
case E_GUI_ID_LOAD_MODEL_MESH:
env->addFileOpenDialog(L"Open main model file", true, 0,
E_GUI_ID_LOAD_MODEL_MESH);
{
std::thread thread(dialog::showFileOpen, env,
E_GUI_ID_LOAD_MODEL_MESH, "Open main model file",
dialog::model_filters, dialog::model_filter_count);
thread.detach();
break;
}
case E_GUI_ID_LOAD_WIELD_MESH:
env->addFileOpenDialog(L"Open wield model file", true, 0,
E_GUI_ID_LOAD_WIELD_MESH);
{
std::thread thread(dialog::showFileOpen, env,
E_GUI_ID_LOAD_WIELD_MESH, "Open wield model file",
dialog::model_filters, dialog::model_filter_count);
thread.detach();
break;
}
case E_GUI_ID_ENABLE_WIELD:
{
ISceneNode *wield = scene->getNode(E_SCENE_ID_WIELD);
@ -289,44 +301,38 @@ bool Viewer::OnEvent(const SEvent &event)
}
else if (event.GUIEvent.EventType == EGET_FILE_SELECTED)
{
IGUIFileOpenDialog *dialog =
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
stringc fn = stringc(dialog->getFileName()).c_str();
if (!fn.empty())
{
s32 id = dialog->getID();
switch (id)
{
case E_GUI_ID_LOAD_MODEL_MESH:
{
if (scene->loadModelMesh(fn))
{
ISceneNode *model = scene->getNode(E_SCENE_ID_MODEL);
if (model)
{
animation->load(model);
setCaptionFileName(fn);
gui->reloadToolBox(E_GUI_ID_TOOLBOX_MODEL);
conf->set("model_mesh", fn.c_str());
}
}
break;
}
case E_GUI_ID_LOAD_WIELD_MESH:
{
if (scene->loadWieldMesh(fn))
{
gui->reloadToolBox(E_GUI_ID_TOOLBOX_WIELD);
conf->set("wield_mesh", fn.c_str());
}
break;
}
default:
break;
}
}
stringc fn = dialog::filename;
s32 id = event.UserEvent.UserData1;
gui->setFocused(false);
switch (id)
{
case E_GUI_ID_LOAD_MODEL_MESH:
{
if (!fn.empty() && scene->loadModelMesh(fn))
{
ISceneNode *model = scene->getNode(E_SCENE_ID_MODEL);
if (model)
{
animation->load(model);
setCaptionFileName(fn);
gui->reloadToolBox(E_GUI_ID_TOOLBOX_MODEL);
conf->set("model_mesh", fn.c_str());
}
}
return true;
}
case E_GUI_ID_LOAD_WIELD_MESH:
{
if (!fn.empty() && scene->loadWieldMesh(fn))
{
gui->reloadToolBox(E_GUI_ID_TOOLBOX_WIELD);
conf->set("wield_mesh", fn.c_str());
}
return true;
}
default:
break;
}
}
else if (event.GUIEvent.EventType == EGET_FILE_CHOOSE_DIALOG_CANCELLED)
{