mirror of
https://github.com/Poikilos/SAM-Viewer.git
synced 2023-10-03 07:58:48 -07:00
Use tiny file dialogs
This commit is contained in:
parent
a4de109ba1
commit
224f2d0be1
@ -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})
|
||||
|
@ -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
|
||||
|
||||
|
38
README.md
38
README.md
@ -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.
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
24
src/dialog.h
24
src/dialog.h
@ -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
2157
src/tinyfiledialogs.c
Normal file
File diff suppressed because it is too large
Load Diff
132
src/tinyfiledialogs.h
Normal file
132
src/tinyfiledialogs.h
Normal 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).
|
||||
*/
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user