2021-03-20 22:42:48 -07:00
# include "Debug.h"
# include "Engine.h"
# include "Utility.h"
2010-04-21 07:48:36 -07:00
# include "UserInterface.h"
2021-03-22 09:21:01 -07:00
// class View : public irr::IEventReceiver; // avoid incomplete type when accessing member of this type from friend class
# include "View.h" // avoid incomplete type when accessing member of this type from friend class
2021-03-20 22:42:48 -07:00
2019-03-09 05:56:23 -08:00
# include <algorithm>
2019-04-11 01:31:04 -07:00
# include <iostream>
# include <string>
2019-03-09 09:51:25 -08:00
// NOTE: to use filesystem, you must also include the fs library such
// as via the `-lstdc++fs` linker option -- see b3view.pro
2019-03-09 09:47:08 -08:00
// #include <filesystem> // requires C++17
2019-04-11 01:31:04 -07:00
# include <experimental/filesystem> // requires C++14 such as gcc 8.2.1
2010-04-21 07:48:36 -07:00
2019-03-09 12:42:40 -08:00
2019-03-07 19:18:07 -08:00
using namespace irr ;
using namespace irr : : core ;
using namespace irr : : gui ;
using std : : string ;
using std : : wstring ;
2019-03-07 23:30:06 -08:00
using namespace std ;
// C++14: namespace filesystem = std::experimental::filesystem;
// namespace fs = std::filesystem; // doesn't work (not a namespace in gcc's C++17)
// using namespace std::filesystem; // doesn't work (not a namespace in gcc's C++17)
namespace fs = std : : experimental : : filesystem ;
2021-03-20 22:42:48 -07:00
// namespace fs = std::filesystem; // doesn't work (not a namespace in gcc's C++17)
2021-03-22 09:21:01 -07:00
2021-03-20 22:42:48 -07:00
const u32 UserInterface : : UIC_FILE_RECENT_FIRST = UIE_RECENTMENU + 1 ;
2019-03-07 19:18:07 -08:00
2010-04-21 07:48:36 -07:00
// PRIVATE
void UserInterface : : setupUserInterface ( )
{
2021-03-28 05:50:51 -07:00
this - > recent_initialized = false ;
this - > recentMenu = nullptr ;
2021-11-28 13:17:17 -08:00
bool enableVerbose = false ;
if ( this - > m_Engine ! = nullptr ) {
enableVerbose = this - > m_Engine - > m_EnableVerbose ;
} else {
std : : cerr < < " Error: The engine is not ready in setupUserInterface. " < < std : : endl ;
}
2019-03-07 10:23:54 -08:00
// Menu
2019-04-08 19:52:18 -07:00
menu = m_Gui - > addMenu ( ) ;
2021-03-29 10:54:27 -07:00
this - > fileMenuIdx = menu - > addItem ( L " File " , UIE_FILEMENU , true , true ) ;
this - > playbackMenuIdx = menu - > addItem ( L " Playback " , UIE_PLAYBACKMENU , true , true ) ;
this - > viewMenuIdx = menu - > addItem ( L " View " , UIE_VIEWMENU , true , true ) ;
2010-04-21 07:48:36 -07:00
2019-03-07 10:23:54 -08:00
// File Menu
2021-03-29 10:54:27 -07:00
fileMenu = menu - > getSubMenu ( this - > fileMenuIdx ) ;
2019-04-19 12:29:30 -07:00
fileMenu - > addItem ( L " Open " , UIC_FILE_OPEN ) ;
2021-02-18 06:31:03 -08:00
this - > fileRecentIdx = fileMenu - > addItem ( L " Open Recent " , UIC_FILE_RECENT , true , true ) ;
std : : vector < std : : string > recentPaths = this - > m_Engine - > recentPaths ( ) ;
2021-03-29 10:54:27 -07:00
fileMenu - > addItem ( L " Reload Model F5 " , UIC_FILE_RELOAD_MESH ) ;
fileMenu - > addItem ( L " Reload Texture Shift F5 " , UIC_FILE_RELOAD_TEXTURE ) ;
2019-04-19 12:29:30 -07:00
fileMenu - > addItem ( L " Change Texture " , UIC_FILE_OPEN_TEXTURE ) ;
2019-04-19 12:50:06 -07:00
fileMenu - > addItem ( L " Previous Texture Shift F3 " , UIC_FILE_PREVIOUS_TEXTURE ) ;
fileMenu - > addItem ( L " Next Texture F3 " , UIC_FILE_NEXT_TEXTURE ) ;
2019-05-16 09:33:53 -07:00
fileMenu - > addItem ( L " Export DAE (non-Blender COLLADA) " , UIC_FILE_EXPORT_DAE ) ;
2019-05-17 05:07:39 -07:00
fileMenu - > addItem ( L " Export IRR (Irrlicht Scene settings and mesh paths only) " , UIC_FILE_EXPORT_IRR ) ;
2019-05-16 09:33:53 -07:00
fileMenu - > addItem ( L " Export IRRMESH (Static Irrlicht Mesh) " , UIC_FILE_EXPORT_IRRMESH ) ;
fileMenu - > addItem ( L " Export OBJ (Wavefront) " , UIC_FILE_EXPORT_OBJ ) ;
fileMenu - > addItem ( L " Export STL (stereolithography) " , UIC_FILE_EXPORT_STL ) ;
2019-04-11 01:31:04 -07:00
fileMenu - > addItem ( L " Quit " , UIC_FILE_QUIT ) ;
2010-04-21 07:48:36 -07:00
2021-02-18 06:31:03 -08:00
// File, Open Recent submenu
this - > recentMenu = fileMenu - > getSubMenu ( this - > fileRecentIdx ) ;
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
std : : cerr < < " +this->recentMenu text: \" " < < Utility : : toString ( ( wstring ) this - > recentMenu - > getText ( ) ) < < " \" "
< < " idx: " < < Utility : : toString ( ( int ) this - > fileRecentIdx )
< < " id: " < < Utility : : toString ( ( int ) this - > recentMenu - > getID ( ) )
< < std : : endl ;
}
2021-03-29 10:54:27 -07:00
this - > fileRecentClearIdx = this - > recentMenu - > addItem ( L " Clear Recent " , UIC_FILE_RECENT_CLEAR ) ;
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
std : : cerr < < " +this->fileRecentClearIdx: " < < this - > fileRecentClearIdx < < std : : endl ;
}
2021-03-20 22:42:48 -07:00
this - > uic_file_recent_next = UserInterface : : UIC_FILE_RECENT_FIRST ;
2021-02-18 06:31:03 -08:00
this - > m_file_recent_first_idx = - 1 ;
this - > m_file_recent_last_idx = - 1 ;
2021-03-20 22:42:48 -07:00
this - > recent_initialized = true ;
this - > addRecentMenuItems ( recentPaths , false ) ;
2021-02-18 06:31:03 -08:00
2019-06-13 05:57:32 -07:00
// Playback Menu
2021-03-29 10:54:27 -07:00
playbackMenu = menu - > getSubMenu ( this - > playbackMenuIdx ) ;
2019-06-13 05:57:32 -07:00
playbackMenu - > addItem ( L " Previous Frame Left " ,
UIC_PLAYBACK_PREVIOUS , true , false ,
false , false ) ;
playbackMenu - > addItem ( L " Next Frame Right " ,
UIC_PLAYBACK_NEXT , true , false ,
false , false ) ;
playbackMenu - > addItem ( L " Slower Ctrl Left " ,
UIC_PLAYBACK_SLOWER , true , false ,
false , false ) ;
playbackMenu - > addItem ( L " Faster Ctrl Right " ,
UIC_PLAYBACK_FASTER , true , false ,
false , false ) ;
2010-08-16 05:23:20 -07:00
// View Menu
2021-03-29 10:54:27 -07:00
viewMenu = menu - > getSubMenu ( this - > viewMenuIdx ) ;
2019-04-19 14:13:58 -07:00
viewWireframeIdx = viewMenu - > addItem ( L " Wireframe " ,
UIC_VIEW_WIREFRAME , true ,
2019-07-03 12:15:44 -07:00
false , this - > m_Engine - > getEnableWireframe ( ) , true ) ;
2019-04-19 14:13:58 -07:00
viewLightingIdx = viewMenu - > addItem ( L " Lighting " ,
UIC_VIEW_LIGHTING , true ,
2019-07-03 12:15:44 -07:00
false , this - > m_Engine - > getEnableLighting ( ) , true ) ;
2019-04-19 14:13:58 -07:00
viewAxisWidgetIdx = viewMenu - > addItem ( L " Origin Axis Widget " ,
UIC_VIEW_AXIS_WIDGET , true , false ,
true , true ) ;
viewTargetIdx = viewMenu - > addItem ( L " Camera Target " ,
UIC_VIEW_TARGET , true , false ,
false , true ) ;
viewTextureInterpolationIdx = viewMenu - > addItem ( L " Texture Interpolation Ctrl i " ,
UIC_VIEW_TEXTURE_INTERPOLATION , true , false ,
2019-07-03 12:15:44 -07:00
this - > m_Engine - > getEnableTextureInterpolation ( ) , true ) ;
2019-04-19 14:13:58 -07:00
viewYUpIdx = viewMenu - > addItem ( L " Y Up " ,
UIC_VIEW_Y_UP , true , false ,
true , true ) ;
viewZUpIdx = viewMenu - > addItem ( L " Z Up " ,
UIC_VIEW_Z_UP , true , false ,
false , true ) ;
2010-08-16 05:23:20 -07:00
2019-03-07 21:52:29 -08:00
// Playback Control Window
dimension2d < u32 > windowSize = m_Engine - > m_Driver - > getScreenSize ( ) ;
2019-04-10 23:30:48 -07:00
playbackWindow = m_Gui - > addWindow (
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( windowSize . Width - 4 - 160 , 28 ) ,
2021-11-27 09:40:35 -08:00
dimension2d < s32 > ( 160 , 500 ) ) ,
2019-04-19 14:13:58 -07:00
false ,
L " Playback " ,
nullptr ,
UIE_PLAYBACKWINDOW
) ;
2019-04-11 01:31:04 -07:00
playbackWindow - > getCloseButton ( ) - > setVisible ( false ) ;
2019-03-07 21:52:29 -08:00
s32 spacing_x = 4 ;
2019-04-19 12:29:30 -07:00
s32 margin_y = 4 ;
2019-04-11 01:31:04 -07:00
spacing_y = 4 ;
2019-03-07 21:52:29 -08:00
s32 size_x = playbackWindow - > getClientRect ( ) . getWidth ( ) - 8 ;
s32 size_y = 24 ;
s32 y = 24 ;
2020-07-30 20:40:17 -07:00
playbackStartFrameStaticText = m_Gui - > addStaticText (
L " Start Frame: " ,
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
true ,
true ,
playbackWindow ,
UIE_PLAYBACKSTARTFRAMESTATICTEXT ,
false ) ;
y + = size_y ;
playbackStartFrameEditBox = m_Gui - > addEditBox (
L " " ,
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
true ,
playbackWindow ,
UIE_PLAYBACKSTARTFRAMEEDITBOX ) ;
y + = size_y + spacing_y ;
playbackEndFrameStaticText = m_Gui - > addStaticText (
L " End Frame: " ,
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
true ,
true ,
playbackWindow ,
UIE_PLAYBACKENDFRAMESTATICTEXT ,
false ) ;
y + = size_y ;
playbackEndFrameEditBox = m_Gui - > addEditBox (
L " " ,
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
true ,
playbackWindow ,
UIE_PLAYBACKENDFRAMEEDITBOX ) ;
y + = size_y + spacing_y ;
2019-03-07 21:52:29 -08:00
playbackStartStopButton = m_Gui - > addButton (
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-11 01:31:04 -07:00
playbackWindow ,
UIE_PLAYBACKSTARTSTOPBUTTON ,
L " Start/Stop " ,
nullptr ) ;
2019-04-19 12:29:30 -07:00
y + = size_y + spacing_y ;
playbackSetFrameEditBox = m_Gui - > addEditBox (
L " " ,
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-19 12:29:30 -07:00
true ,
playbackWindow ,
UIE_PLAYBACKSETFRAMEEDITBOX ) ;
y + = margin_y ;
2019-03-07 21:52:29 -08:00
y + = size_y + spacing_y ;
playbackIncreaseButton = m_Gui - > addButton (
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-11 01:31:04 -07:00
playbackWindow ,
UIE_PLAYBACKINCREASEBUTTON ,
L " Faster " ,
nullptr ) ;
2019-04-19 12:29:30 -07:00
2019-03-07 21:52:29 -08:00
y + = size_y + spacing_y ;
playbackDecreaseButton = m_Gui - > addButton (
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-11 01:31:04 -07:00
playbackWindow ,
UIE_PLAYBACKDECREASEBUTTON ,
L " Slower " ,
nullptr ) ;
2010-04-23 01:13:44 -07:00
2019-04-03 07:35:27 -07:00
y + = size_y + spacing_y ;
2019-04-19 12:29:30 -07:00
playbackFPSEditBox = m_Gui - > addEditBox (
2019-04-03 07:35:27 -07:00
L " " ,
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-03 07:35:27 -07:00
true ,
playbackWindow ,
2019-04-19 12:29:30 -07:00
UIE_FPSEDITBOX ) ;
y + = margin_y ;
2019-04-03 07:35:27 -07:00
2019-04-08 19:52:18 -07:00
y + = size_y + spacing_y ;
texturePathStaticText = m_Gui - > addStaticText (
L " Texture Path: " ,
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-08 19:52:18 -07:00
true ,
true ,
playbackWindow ,
UIE_TEXTUREPATHSTATICTEXT ,
2019-04-11 01:31:04 -07:00
false ) ;
2019-04-19 12:29:30 -07:00
2019-04-08 19:52:18 -07:00
y + = size_y + spacing_y ;
texturePathEditBox = m_Gui - > addEditBox (
L " " ,
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-08 19:52:18 -07:00
true ,
playbackWindow ,
2019-04-11 01:31:04 -07:00
UIE_TEXTUREPATHEDITBOX ) ;
2021-11-27 14:41:47 -08:00
texturePathEditBox - > setTextAlignment ( EGUIA_LOWERRIGHT , EGUIA_UPPERLEFT ) ;
2019-04-19 12:29:30 -07:00
y + = margin_y ;
y + = size_y + spacing_y ;
axisSizeStaticText = m_Gui - > addStaticText (
L " Axis Size: " ,
2019-04-19 14:34:31 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
2019-04-19 14:13:58 -07:00
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-19 12:29:30 -07:00
true ,
true ,
playbackWindow ,
UIE_AXISSIZESTATICTEXT ,
false ) ;
y + = size_y + spacing_y ;
axisSizeEditBox = m_Gui - > addEditBox (
2020-03-10 11:12:16 -07:00
std : : to_wstring ( this - > m_Engine - > m_AxisLength ) . c_str ( ) ,
2019-04-19 14:13:58 -07:00
rect < s32 > ( vector2d < s32 > ( spacing_x , y ) ,
dimension2d < s32 > ( size_x , size_y ) ) ,
2019-04-19 12:29:30 -07:00
true ,
playbackWindow ,
UIE_AXISSIZEEDITBOX ) ;
y + = margin_y ;
y + = size_y + spacing_y ;
2019-04-08 19:52:18 -07:00
2010-04-21 07:48:36 -07:00
// Set Font for UI Elements
2010-04-23 01:13:44 -07:00
m_GuiFontFace = new CGUITTFace ( ) ;
2019-03-07 19:18:07 -08:00
// irrString defines stringc as string<c8>
2019-03-09 13:41:56 -08:00
if ( ! Utility : : isFile ( m_Engine - > m_FontPath ) ) {
m_Engine - > m_FontPath = L " C: \\ Windows \\ Fonts \\ calibrib.ttf " ;
}
if ( ! Utility : : isFile ( m_Engine - > m_FontPath ) ) {
m_Engine - > m_FontPath = L " C: \\ Windows \\ Fonts \\ arialbd.ttf " ;
}
if ( ! Utility : : isFile ( m_Engine - > m_FontPath ) ) {
2019-03-09 14:15:50 -08:00
m_Engine - > m_FontPath = L " /usr/share/fonts/liberation/LiberationSans-Bold.ttf " ;
2019-03-09 13:41:56 -08:00
}
if ( ! Utility : : isFile ( m_Engine - > m_FontPath ) ) {
2019-03-09 14:15:50 -08:00
m_Engine - > m_FontPath = L " /usr/share/fonts/gnu-free/FreeSansBold.ttf " ;
2019-03-09 13:41:56 -08:00
}
if ( ! Utility : : isFile ( m_Engine - > m_FontPath ) ) {
m_Engine - > m_FontPath = L " /usr/share/fonts/dejavu/DejaVuSans-Bold.ttf " ;
}
if ( ! Utility : : isFile ( m_Engine - > m_FontPath ) ) {
m_Engine - > m_FontPath = L " /usr/share/fonts/google-droid/DroidSans-Bold.ttf " ;
}
2021-03-28 03:56:19 -07:00
if ( ! Utility : : isFile ( m_Engine - > m_FontPath ) ) {
m_Engine - > m_FontPath = L " /usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf " ;
// ^ This is present on Debian 10. No previous fonts further up are.
}
// if (!Utility::isFile(m_Engine->m_FontPath)) {
// m_Engine->m_FontPath = L"/usr/share/fonts-droid-fallback/truetype/DroidSansFallback.ttf";
// /usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf
// ^ These are CJK fonts!
// }
2019-03-09 13:41:56 -08:00
2019-04-11 01:31:04 -07:00
if ( m_GuiFontFace - > load ( m_Engine - > m_FontPath . c_str ( ) ) ) { // actually takes `const io::path &`
m_GuiFont = new CGUITTFont ( m_Gui ) ;
m_GuiFont - > attach ( m_GuiFontFace , 14 ) ;
m_Gui - > getSkin ( ) - > setFont ( m_GuiFont ) ;
} else {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
std : : wcerr < < L " WARNING: ' " < < m_Engine - > m_FontPath < < L " ' is missing. "
< < endl ;
}
2019-03-07 19:18:07 -08:00
delete m_GuiFontFace ;
m_GuiFontFace = nullptr ;
if ( m_GuiFont ! = nullptr ) {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
std : : wcerr < < L " - The old font will remain loaded. " < < endl ;
}
2019-03-07 19:18:07 -08:00
}
2019-03-07 10:23:54 -08:00
}
2019-04-19 14:16:28 -07:00
// }
2010-04-21 07:48:36 -07:00
}
void UserInterface : : displayLoadFileDialog ( )
{
2021-03-28 04:05:15 -07:00
m_Gui - > addFileOpenDialog ( L " Select a file to load " ,
2019-04-19 14:13:58 -07:00
true , nullptr , UIE_LOADFILEDIALOG ) ;
2010-04-21 07:48:36 -07:00
}
2019-05-02 18:17:24 -07:00
void UserInterface : : displaySaveFileDialog ( )
{
m_Gui - > addFileOpenDialog ( L " Select where to save export.dae " ,
true , nullptr , UIE_SAVEFILEDIALOG ) ;
// NOTE: if restoreCWD is false (default), cwd changes.
}
2019-03-07 14:17:42 -08:00
void UserInterface : : displayLoadTextureDialog ( )
{
2021-03-28 04:05:15 -07:00
m_Gui - > addFileOpenDialog ( L " Select a file to load " ,
2019-04-19 14:13:58 -07:00
true , nullptr , UIE_LOADTEXTUREDIALOG ) ;
2019-03-07 14:17:42 -08:00
}
2019-06-13 05:57:32 -07:00
void UserInterface : : incrementFrame ( f32 frameCount , bool enableRound )
{
if ( this - > m_Engine - > m_LoadedMesh ! = nullptr ) {
2020-03-10 11:12:16 -07:00
if ( this - > m_Engine - > m_IsPlaying )
2019-06-13 05:57:32 -07:00
this - > m_Engine - > toggleAnimation ( ) ;
this - > m_Engine - > m_LoadedMesh - > setCurrentFrame (
enableRound
? ( round ( this - > m_Engine - > m_LoadedMesh - > getFrameNr ( ) ) + frameCount )
: ( round ( this - > m_Engine - > m_LoadedMesh - > getFrameNr ( ) ) + frameCount )
) ;
this - > playbackSetFrameEditBox - > setText (
Utility : : toWstring (
this - > m_Engine - > m_LoadedMesh - > getFrameNr ( )
) . c_str ( )
) ;
}
}
2021-03-22 08:22:21 -07:00
bool UserInterface : : handleMenuItemPressed ( const SEvent : : SGUIEvent * ge )
2010-04-23 00:28:59 -07:00
{
2021-03-22 08:22:21 -07:00
// ^ formerly ...(IGUIContextMenu* menu): called as ...(static_cast<IGUIContextMenu*>(ge->Caller)); protytyped as ...(irr::gui::IGUIContextMenu* menu)
bool handled = true ;
IGUIContextMenu * menu = static_cast < IGUIContextMenu * > ( ge - > Caller ) ;
s32 callerID = ge - > Caller - > getID ( ) ;
2019-04-10 23:39:12 -07:00
s32 selected = menu - > getSelectedItem ( ) ;
2021-03-22 16:34:34 -07:00
s32 commandID = menu - > getItemCommandId ( static_cast < u32 > ( selected ) ) ;
2021-11-28 13:17:17 -08:00
bool enableVerbose = this - > m_Engine - > m_EnableVerbose ;
2021-03-22 09:55:24 -07:00
switch ( callerID ) {
case UIE_RECENTMENU :
// if ((ge->Caller->getID() >= this->m_file_recent_first_idx)
// && (ge->Caller->getID() <= m_file_recent_last_idx)) {
// NOTE: ge->Caller->getID() is probably UIE_RECENTMENU now, but that is not to be used directly!
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " selected " < < selected < < std : : endl ;
}
2021-03-29 10:54:27 -07:00
if ( std : : find ( this - > recentIndices . begin ( ) , this - > recentIndices . end ( ) , commandID ) ! = this - > recentIndices . end ( ) ) {
2021-03-22 09:55:24 -07:00
// ge->Caller->getText() // Don't do this. Caller is the parent!
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " parent callerID: " < < callerID < < endl ;
// ^ callerID is the parent such as 1100 (or whatever UI_RECENTMENU is)
cerr < < " commandID: " < < commandID < < std : : endl ;
// ^ commandID is a menu id specified on creation
// such as starting from 1101
// or from whatever UIC_FILE_RECENT_FIRST is--usually UI_RECENTMENU+1).
// selectedItemID is a sequential number.
}
2021-03-22 16:34:34 -07:00
// std::wstring menuItemText = menu->getItemText(selected);
2021-03-29 10:54:27 -07:00
this - > openRecent ( commandID , selected ) ;
2021-03-22 09:55:24 -07:00
}
else {
2021-03-29 10:54:27 -07:00
cerr < < " Unknown commandID: " < < commandID < < " Text: " < < Utility : : toString ( menu - > getItemText ( selected ) ) < < endl ;
// ^ getItemText takes the index (NOT the commandID specified on creation)
2021-03-22 09:55:24 -07:00
if ( this - > recentIndices . size ( ) < 1 ) {
2021-11-28 13:17:17 -08:00
2021-03-22 09:55:24 -07:00
cerr < < " - recentIndices.size(): " < < recentIndices . size ( ) < < endl ;
}
else {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " recentIndices: " < < recentIndices . size ( ) < < endl ;
// range based for loop requires C++11 or higher:
for ( irr : : u32 i : this - > recentIndices ) {
cerr < < " - " < < i < < endl ;
}
2021-03-22 09:55:24 -07:00
}
}
handled = false ;
}
2019-04-10 23:39:12 -07:00
2021-03-22 16:34:34 -07:00
// cerr << "[UserInterface::handleMenuItemPressed] Unknown caller id: " << callerID << endl;
2021-03-22 09:55:24 -07:00
break ;
default :
//if (selected > -1) {
cerr < < " Some other menu was used: " < < callerID
< < " Text: " < < Utility : : toString ( menu - > getItemText ( selected ) )
< < std : : endl ;
cerr < < " - checking command id... "
< < std : : endl ;
2021-03-22 16:34:34 -07:00
switch ( commandID ) {
2019-04-19 12:29:30 -07:00
case UIC_FILE_OPEN :
2019-04-10 23:39:12 -07:00
displayLoadFileDialog ( ) ;
break ;
2021-02-18 06:31:03 -08:00
case UIC_FILE_RECENT_CLEAR :
clearRecent ( ) ;
break ;
2019-05-16 09:33:53 -07:00
case UIC_FILE_EXPORT_DAE :
exportMeshToHome ( " dae " ) ;
break ;
case UIC_FILE_EXPORT_IRR :
exportMeshToHome ( " irr " ) ;
break ;
case UIC_FILE_EXPORT_IRRMESH :
exportMeshToHome ( " irrmesh " ) ;
break ;
case UIC_FILE_EXPORT_OBJ :
exportMeshToHome ( " obj " ) ;
break ;
case UIC_FILE_EXPORT_STL :
exportMeshToHome ( " stl " ) ;
2019-05-02 18:17:24 -07:00
break ;
2021-03-29 10:54:27 -07:00
case UIC_FILE_RELOAD_MESH :
m_Engine - > reloadMesh ( ) ;
break ;
case UIC_FILE_RELOAD_TEXTURE :
m_Engine - > reloadTexture ( ) ;
break ;
2019-04-19 12:29:30 -07:00
case UIC_FILE_OPEN_TEXTURE :
2019-05-16 09:33:53 -07:00
if ( m_Engine - > m_LoadedMesh ! = nullptr ) {
displayLoadTextureDialog ( ) ;
}
else {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Change Texture " , L " You must load a model before a texture. " ) ;
}
2019-04-10 23:39:12 -07:00
break ;
2019-04-19 12:29:30 -07:00
case UIC_FILE_PREVIOUS_TEXTURE :
2019-05-16 09:33:53 -07:00
if ( m_Engine - > m_LoadedMesh ! = nullptr ) {
loadNextTexture ( - 1 ) ;
}
else {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Change Texture " , L " You must load a model before a texture. " ) ;
}
2019-04-19 12:29:30 -07:00
break ;
case UIC_FILE_NEXT_TEXTURE :
2019-05-16 09:33:53 -07:00
if ( m_Engine - > m_LoadedMesh ! = nullptr ) {
loadNextTexture ( 1 ) ;
}
else {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Change Texture " , L " You must load a model before a texture. " ) ;
}
2019-04-19 12:29:30 -07:00
break ;
2019-04-10 23:39:12 -07:00
case UIC_FILE_QUIT :
m_Engine - > m_RunEngine = false ;
break ;
2019-06-13 05:57:32 -07:00
case UIC_PLAYBACK_PREVIOUS :
this - > incrementFrame ( - 1.0f , true ) ;
break ;
case UIC_PLAYBACK_NEXT :
this - > incrementFrame ( 1.0f , true ) ;
break ;
case UIC_PLAYBACK_SLOWER :
//if (ge->EventType == EGET_BUTTON_CLICKED) {
this - > m_Engine - > incrementAnimationFPS ( - 5 ) ;
//}
break ;
case UIC_PLAYBACK_FASTER :
//if (ge->EventType == EGET_BUTTON_CLICKED) {
this - > m_Engine - > incrementAnimationFPS ( 5 ) ;
//}
break ;
2019-04-19 12:29:30 -07:00
case UIC_VIEW_TARGET :
//
break ;
case UIC_VIEW_Y_UP :
m_Engine - > setZUp ( false ) ;
viewMenu - > setItemChecked ( viewZUpIdx , false ) ;
break ;
case UIC_VIEW_Z_UP :
m_Engine - > setZUp ( true ) ;
viewMenu - > setItemChecked ( viewYUpIdx , false ) ;
break ;
2019-07-03 12:15:44 -07:00
case UIC_VIEW_WIREFRAME :
m_Engine - > setEnableWireframe (
! m_Engine - > getEnableWireframe ( )
) ;
viewMenu - > setItemChecked (
viewWireframeIdx ,
m_Engine - > getEnableWireframe ( )
) ;
break ;
case UIC_VIEW_LIGHTING :
m_Engine - > setEnableLighting (
! m_Engine - > getEnableLighting ( )
) ;
viewMenu - > setItemChecked (
viewLightingIdx ,
m_Engine - > getEnableLighting ( )
) ;
break ;
2019-04-10 23:39:12 -07:00
case UIC_VIEW_TEXTURE_INTERPOLATION :
2019-07-03 12:15:44 -07:00
m_Engine - > setEnableTextureInterpolation (
! m_Engine - > getEnableTextureInterpolation ( )
) ;
viewMenu - > setItemChecked (
viewTextureInterpolationIdx ,
m_Engine - > getEnableTextureInterpolation ( )
2019-04-19 14:13:58 -07:00
) ;
2019-04-10 23:39:12 -07:00
break ;
2021-03-22 07:38:02 -07:00
default :
2021-03-22 16:34:34 -07:00
cerr < < " Unknown command id: " < < commandID < < " Text: " < < Utility : : toString ( menu - > getItemText ( selected ) ) < < endl ;
2021-03-22 07:38:02 -07:00
break ;
2019-04-10 23:39:12 -07:00
}
2021-03-22 09:55:24 -07:00
break ;
2010-04-23 00:28:59 -07:00
}
2021-03-22 08:22:21 -07:00
return handled ;
2019-04-11 01:31:04 -07:00
}
2019-04-08 19:52:18 -07:00
2019-07-03 12:15:44 -07:00
void UserInterface : : updateSettingsDisplay ( )
{
viewMenu - > setItemChecked (
viewWireframeIdx ,
m_Engine - > getEnableWireframe ( )
) ;
viewMenu - > setItemChecked (
viewLightingIdx ,
m_Engine - > getEnableLighting ( )
) ;
viewMenu - > setItemChecked (
viewTextureInterpolationIdx ,
m_Engine - > getEnableTextureInterpolation ( )
) ;
}
2019-04-11 01:31:04 -07:00
void UserInterface : : snapWidgets ( )
{
dimension2d < u32 > screenSize = m_Engine - > m_Driver - > getScreenSize ( ) ;
rect < s32 > newRect ;
2019-04-19 14:16:28 -07:00
// newRect.LowerRightCorner.X = static_cast<s32>(size.Width);
// newRect.LowerRightCorner.Y = static_cast<s32>(size.Height);
2019-04-11 01:31:04 -07:00
rect < s32 > prevRect = playbackWindow - > getRelativePosition ( ) ;
2019-04-19 14:13:58 -07:00
newRect . UpperLeftCorner . X = static_cast < s32 > ( screenSize . Width )
- prevRect . getWidth ( ) - spacing_y ;
// debug() << "screen size: " << screenSize.Width << "x" << screenSize.Height;
// debug() << " prevRect: "
// << prevRect.UpperLeftCorner.X << ","
// << prevRect.UpperLeftCorner.Y << ","
// << prevRect.LowerRightCorner.X << ","
// << prevRect.LowerRightCorner.Y
// << " size=(" << prevRect.getWidth() << ","
// << prevRect.getHeight() << ")" << endl;
2019-04-11 01:31:04 -07:00
newRect . UpperLeftCorner . Y = prevRect . UpperLeftCorner . Y ;
2019-04-19 14:13:58 -07:00
newRect . LowerRightCorner . X = newRect . UpperLeftCorner . X
+ prevRect . getWidth ( ) ;
newRect . LowerRightCorner . Y = newRect . UpperLeftCorner . Y
+ prevRect . getHeight ( ) ;
2019-04-11 01:31:04 -07:00
playbackWindow - > setRelativePosition ( newRect ) ;
m_WindowSize . Width = m_Engine - > m_Driver - > getScreenSize ( ) . Width ;
m_WindowSize . Height = m_Engine - > m_Driver - > getScreenSize ( ) . Height ;
2010-04-23 00:28:59 -07:00
}
2010-04-21 07:48:36 -07:00
// PUBLIC
2019-04-11 01:31:04 -07:00
UserInterface : : UserInterface ( Engine * engine )
2010-04-21 07:48:36 -07:00
{
2021-03-20 22:42:48 -07:00
this - > recent_initialized = false ;
2019-04-19 12:29:30 -07:00
viewTextureInterpolationIdx = 0 ;
viewWireframeIdx = 0 ;
viewLightingIdx = 0 ;
2019-03-07 21:52:29 -08:00
this - > playbackStartStopButton = nullptr ;
2010-04-21 07:48:36 -07:00
m_Engine = engine ;
m_Gui = engine - > getGUIEnvironment ( ) ;
2019-04-10 23:30:48 -07:00
playbackWindow = nullptr ;
2010-08-16 05:23:20 -07:00
2010-04-21 07:48:36 -07:00
setupUserInterface ( ) ;
}
UserInterface : : ~ UserInterface ( )
{
delete m_GuiFont ;
2010-04-23 01:13:44 -07:00
delete m_GuiFontFace ;
2010-04-21 07:48:36 -07:00
}
2019-04-11 01:31:04 -07:00
IGUIEnvironment * UserInterface : : getGUIEnvironment ( ) const
2010-04-21 07:48:36 -07:00
{
return m_Gui ;
}
2010-04-23 00:28:59 -07:00
void UserInterface : : drawStatusLine ( ) const
2010-04-21 07:48:36 -07:00
{
}
2020-03-10 11:12:16 -07:00
bool UserInterface : : OnSelectMesh ( ) {
this - > m_MatchingTextures . clear ( ) ;
this - > m_AllTextures . clear ( ) ;
return true ;
}
2020-07-30 20:40:17 -07:00
void UserInterface : : setPlaybackText ( s32 id , const wchar_t * text )
{
switch ( id ) {
case ( UIE_PLAYBACKSTARTFRAMEEDITBOX ) :
this - > playbackStartFrameEditBox - > setText ( text ) ;
break ;
case ( UIE_PLAYBACKENDFRAMEEDITBOX ) :
this - > playbackEndFrameEditBox - > setText ( text ) ;
break ;
default :
std : : cerr < < " ERROR: setPlaybackText got a bad id: " < < id < < std : : endl ;
// break;
}
}
2020-03-10 11:12:16 -07:00
/**
* Load the next texture from the list of found textures .
* Files are only listed once for speed , so you must reload the
* model to trigger another list ( " dir " ) operation ( since loading
* a mesh calls OnSelectMesh ( ) which clears allTextures and matchingTextures ) .
*
* @ param direction Specify < 0 to choose previous texture , > 0 for next , 0 to
* reload current texture if any ; otherwise , only select a texture if any
* matching textures ( named like model ) are present in . or . . / textures .
* @ return Any texture was loaded ( true / false ) .
*/
2019-03-07 23:30:06 -08:00
bool UserInterface : : loadNextTexture ( int direction )
{
2021-11-28 13:17:17 -08:00
bool enableVerbose = false ;
if ( this - > m_Engine ! = nullptr ) {
enableVerbose = this - > m_Engine - > m_EnableVerbose ;
}
if ( enableVerbose ) {
cerr < < " Loading texture... " < < flush ;
}
2019-03-07 23:30:06 -08:00
bool ret = false ;
std : : wstring basePath = L " . " ;
2020-03-10 11:12:16 -07:00
if ( this - > m_Engine - > m_LoadedMeshPath . length ( ) > 0 ) {
2019-07-03 14:13:37 -07:00
std : : wstring prevModelName = Utility : : basename (
2020-03-10 11:12:16 -07:00
this - > m_Engine - > m_LoadedMeshPath
2019-04-19 14:13:58 -07:00
) ;
2019-07-03 12:15:44 -07:00
wstring foundPath ;
2019-07-03 14:13:37 -07:00
wstring prevModelNoExt ;
prevModelNoExt = Utility : : withoutExtension ( prevModelName ) ;
2020-03-10 11:12:16 -07:00
/*
2019-07-03 12:15:44 -07:00
vector < wstring > names ;
2019-07-03 14:13:37 -07:00
names . push_back ( prevModelNoExt + L " _mesh " ) ;
names . push_back ( prevModelNoExt ) ;
names . push_back ( prevModelNoExt + L " _1 " ) ;
names . push_back ( prevModelNoExt + L " _2 " ) ;
names . push_back ( prevModelNoExt + L " _1 " ) ;
names . push_back ( prevModelNoExt + L " _2 " ) ;
names . push_back ( prevModelNoExt + L " _01 " ) ;
names . push_back ( prevModelNoExt + L " _02 " ) ;
names . push_back ( prevModelNoExt + L " _01 " ) ;
names . push_back ( prevModelNoExt + L " _02 " ) ;
names . push_back ( prevModelNoExt + L " _child " ) ;
names . push_back ( prevModelNoExt + L " _female " ) ;
names . push_back ( prevModelNoExt + L " _f " ) ;
names . push_back ( prevModelNoExt + L " _male " ) ;
names . push_back ( prevModelNoExt + L " _m " ) ;
2020-03-10 11:12:16 -07:00
*/
2019-07-03 14:13:37 -07:00
vector < wstring > badSuffixes ;
badSuffixes . push_back ( L " _inv " ) ;
2019-07-03 12:15:44 -07:00
2019-04-19 14:13:58 -07:00
std : : wstring lastDirPath = Utility : : parentOfPath (
2020-03-10 11:12:16 -07:00
this - > m_Engine - > m_LoadedMeshPath
2019-04-19 14:13:58 -07:00
) ;
2019-03-07 23:30:06 -08:00
std : : wstring parentPath = Utility : : parentOfPath ( lastDirPath ) ;
2019-04-19 14:13:58 -07:00
std : : wstring dirSeparator = Utility : : delimiter (
2020-03-10 11:12:16 -07:00
this - > m_Engine - > m_LoadedMeshPath
2019-04-19 14:13:58 -07:00
) ;
2019-03-07 23:30:06 -08:00
std : : wstring texturesPath = parentPath + dirSeparator + L " textures " ;
2019-07-03 14:13:37 -07:00
std : : wstring tryTexPath = texturesPath + dirSeparator + prevModelNoExt
2019-04-19 14:13:58 -07:00
+ L " .png " ;
2020-03-10 11:12:16 -07:00
vector < wstring > texturePaths ;
2019-07-03 14:13:37 -07:00
2020-03-10 11:12:16 -07:00
texturePaths . push_back ( lastDirPath ) ;
if ( fs : : is_directory ( fs : : status ( texturesPath ) ) ) {
texturePaths . push_back ( texturesPath ) ;
}
vector < wstring > dotExts ;
for ( auto ext : this - > m_Engine - > m_TextureExtensions ) {
dotExts . push_back ( L " . " + ext ) ;
}
if ( this - > m_MatchingTextures . size ( ) + this - > m_AllTextures . size ( ) < 1 ) {
for ( auto path : texturePaths ) {
for ( const auto & itr : fs : : directory_iterator ( path ) ) {
if ( fs : : is_regular_file ( itr . status ( ) ) ) {
std : : wstring name = itr . path ( ) . filename ( ) . wstring ( ) ;
std : : wstring suffix = Utility : : getSuffix ( name , dotExts ,
true ) ;
bool isUsable = true ;
std : : wstring nameNoExt = Utility : : withoutExtension (
name
) ;
if ( Utility : : endsWithAny ( nameNoExt , badSuffixes , true ) )
isUsable = false ;
if ( isUsable & & suffix . length ( ) > 0 ) {
this - > m_AllTextures . push_back (
path + dirSeparator + name
) ;
if ( Utility : : startsWith ( name , prevModelNoExt ) ) {
this - > m_MatchingTextures . push_back (
path + dirSeparator + name
) ;
2019-07-03 14:13:37 -07:00
}
2020-03-10 11:12:16 -07:00
else if ( name . find ( prevModelNoExt ) ! = std : : wstring : : npos ) {
this - > m_MatchingTextures . push_back (
path + dirSeparator + name
) ;
2019-07-03 14:13:37 -07:00
}
2020-03-10 11:12:16 -07:00
else if ( name . find ( Utility : : replaceAll ( prevModelNoExt , L " _ " , L " " ) ) ! = std : : wstring : : npos ) {
this - > m_MatchingTextures . push_back (
path + dirSeparator + name
) ;
2019-03-08 19:41:59 -08:00
}
2019-03-07 23:30:06 -08:00
}
2019-03-09 05:56:23 -08:00
}
2019-03-07 23:30:06 -08:00
}
}
}
2020-03-10 11:12:16 -07:00
vector < wstring > paths = this - > m_MatchingTextures ;
if ( this - > m_MatchingTextures . size ( ) < 1 ) {
paths = this - > m_AllTextures ;
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
debug ( ) < < " There were no matching textures so "
< < " the entire list of " < < this - > m_AllTextures . size ( )
< < " found textures will be used... " < < std : : flush ;
}
2020-03-10 11:12:16 -07:00
}
else {
// Assume the user wants to view name-matched texture using
// the render settings of Minetest.
this - > m_Engine - > setEnableTextureInterpolation ( false ) ;
viewMenu - > setItemChecked (
viewTextureInterpolationIdx ,
this - > m_Engine - > getEnableTextureInterpolation ( )
) ;
}
std : : wstring prevTexture = L " " ;
std : : wstring nextTexture = L " " ;
std : : wstring lastTexture = L " " ;
std : : wstring firstTexture = L " " ;
bool found = false ;
for ( auto path : paths ) {
if ( firstTexture . length ( ) = = 0 )
firstTexture = path ;
lastTexture = path ;
if ( this - > m_Engine - > m_LoadedTexturePath . length ( ) > 0 ) {
if ( path = = this - > m_Engine - > m_LoadedTexturePath ) {
found = true ;
}
else if ( ! found ) {
prevTexture = path ;
}
else {
if ( nextTexture . length ( ) = = 0 )
nextTexture = path ;
}
}
else {
prevTexture = path ; // Use the last one as the previous.
if ( nextTexture . length ( ) = = 0 )
nextTexture = path ;
}
}
if ( nextTexture . length ( ) = = 0 )
nextTexture = firstTexture ; // The last is current, so next is 1st.
if ( prevTexture . length ( ) = = 0 ) {
if ( lastTexture ! = firstTexture )
prevTexture = lastTexture ; // Wrap to end.
else
prevTexture = firstTexture ; // Use the only texture.
}
if ( lastTexture . length ( ) > 0 ) {
if ( direction < 0 ) {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " loading the previous texture... " ;
}
2021-03-29 11:10:40 -07:00
ret = this - > m_Engine - > loadTexture ( prevTexture , false ) ;
2020-03-10 11:12:16 -07:00
}
else if ( direction > 0 ) {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " loading the next texture... " ;
}
2021-03-29 11:10:40 -07:00
ret = this - > m_Engine - > loadTexture ( nextTexture , false ) ;
2020-03-10 11:12:16 -07:00
}
else {
// If direction is 0 (such as when a model is loaded that has
2021-03-28 03:08:53 -07:00
// no texture), only load a specified or matching texture.
2020-03-10 11:12:16 -07:00
if ( this - > m_Engine - > m_LoadedTexturePath . length ( ) > 0 ) {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " using a specified texture... " ;
}
2020-03-10 11:12:16 -07:00
ret = this - > m_Engine - > loadTexture (
2021-03-29 11:10:40 -07:00
this - > m_Engine - > m_LoadedTexturePath ,
false
2020-03-10 11:12:16 -07:00
) ;
}
else if ( this - > m_MatchingTextures . size ( ) > = 1 ) {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " loading matching texture... " ;
}
2021-03-29 11:10:40 -07:00
ret = this - > m_Engine - > loadTexture ( firstTexture , false ) ;
2020-03-10 11:12:16 -07:00
}
2021-03-28 03:08:53 -07:00
else {
ret = true ;
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " (cycling was off and there is no matching texture) " ;
}
2021-03-28 03:08:53 -07:00
}
2020-03-10 11:12:16 -07:00
}
}
else if ( this - > m_Engine - > m_LoadedTexturePath . length ( ) > 0 ) {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
cerr < < " loading the first texture... " ;
}
2020-03-10 11:12:16 -07:00
ret = this - > m_Engine - > loadTexture (
2021-03-29 11:10:40 -07:00
this - > m_Engine - > m_LoadedTexturePath ,
false
2020-03-10 11:12:16 -07:00
) ;
}
2021-11-28 13:17:17 -08:00
} else {
if ( enableVerbose ) {
debug ( ) < < " Can't cycle texture since no file was opened " < < endl ;
}
}
if ( enableVerbose ) {
cerr < < ( ret ? " OK " : " FAILED " ) < < endl ;
}
2019-03-09 05:56:23 -08:00
return ret ;
2019-03-07 23:30:06 -08:00
}
2019-05-16 09:33:53 -07:00
void UserInterface : : exportMeshToHome ( std : : string extension )
{
if ( this - > m_Engine - > m_LoadedMesh ! = nullptr ) {
// this->m_Engine->m_LoadedMesh->getName();
// displaySaveFileDialog();
irr : : io : : path where = irr : : io : : path ( ) ;
if ( const char * env_p = std : : getenv ( " HOME " ) ) {
// std::cout << "Your PATH is: " << env_p << '\n';
where = irr : : io : : path ( env_p ) ;
std : : cout < < " Your PATH is: " < < where . c_str ( ) < < ' \n ' ;
}
else if ( const char * env_p = std : : getenv ( " USERPROFILE " ) ) {
// std::cout << "Your PATH is: " << env_p << '\n';
where = irr : : io : : path ( env_p ) ;
std : : cout < < " Your PATH is: " < < where . c_str ( ) < < ' \n ' ;
}
std : : string name = " " ;
2020-03-10 11:12:16 -07:00
if ( m_Engine - > m_LoadedMeshPath . length ( ) > 0 ) {
name = Utility : : toString ( Utility : : withoutExtension ( Utility : : basename ( m_Engine - > m_LoadedMeshPath ) ) ) ;
2019-05-16 09:33:53 -07:00
}
2020-01-30 08:46:24 -08:00
2019-05-16 09:33:53 -07:00
wstring result = m_Engine - > saveMesh ( where , name , extension ) ;
std : : wstring caption = L " Export Failed " ;
std : : wstring msg = L " The format or home variable is unwriteable " ;
if ( result . length ( ) > 0 ) {
caption = L " Export Finished " ;
msg = L " Saved " + result ;
}
std : : cout < < " Exported as: " < < Utility : : toString ( result ) < < ' \n ' ;
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
caption . c_str ( ) , msg . c_str ( ) ) ;
}
else {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Export " , L " There is nothing to export. " ) ;
}
}
2021-02-18 06:31:03 -08:00
void UserInterface : : clearRecent ( )
{
2021-03-20 22:42:48 -07:00
// for (int idx=this->uic_file_recent_next-1; idx>=UserInterface::uic_file_recent_first; idx--) {
2021-02-18 06:31:03 -08:00
for ( std : : vector < u32 > : : iterator idxIt = this - > recentIndices . begin ( ) ; idxIt ! = this - > recentIndices . end ( ) ; + + idxIt ) {
this - > recentMenu - > removeItem ( * idxIt ) ;
}
this - > recentIndices . clear ( ) ;
2021-03-20 22:42:48 -07:00
this - > uic_file_recent_next = UserInterface : : UIC_FILE_RECENT_FIRST ;
2021-02-18 06:31:03 -08:00
this - > m_file_recent_first_idx = - 1 ;
this - > m_file_recent_last_idx = - 1 ;
}
2021-03-20 22:42:48 -07:00
void UserInterface : : addRecentMenuItem ( std : : string path , bool addToEngine )
2021-02-18 06:31:03 -08:00
{
2021-11-28 13:17:17 -08:00
bool enableVerbose = false ;
if ( this - > m_Engine ! = nullptr ) {
enableVerbose = this - > m_Engine - > m_EnableVerbose ;
} else {
std : : cerr < < " Error: m_Engine isn't ready in addRecentMenuItem. " < < std : : endl ;
}
2021-03-20 22:42:48 -07:00
if ( ! this - > recent_initialized ) {
2021-03-28 03:56:19 -07:00
throw std : : runtime_error ( " The UI is not ready in addRecentMenuItem. " ) ;
2021-03-20 22:42:48 -07:00
}
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
std : : cerr < < " [addRecentMenuItem] " < < path < < " ... " < < std : : endl ;
}
2021-02-18 06:31:03 -08:00
if ( ! this - > hasRecent ( path ) ) {
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
std : : cerr < < " * adding since new... " < < std : : endl ;
}
2021-03-20 22:42:48 -07:00
wstring path_ws = Utility : : toWstring ( path ) ;
if ( this - > uic_file_recent_next < UserInterface : : UIC_FILE_RECENT_FIRST ) {
2021-03-22 05:32:53 -07:00
throw std : : runtime_error ( " this->uic_file_recent_next is "
+ std : : to_string ( this - > uic_file_recent_next )
+ " but should be equal to or greater than first: "
+ std : : to_string ( this - > uic_file_recent_next ) ) ;
2021-03-20 22:42:48 -07:00
}
2021-03-22 09:55:24 -07:00
// The first this->uic_file_recent_next is 1101 or whatever
// UserInterface::UIC_FILE_RECENT_FIRST (usually UIC_FILE_RECENT+1) is.
2021-03-20 22:42:48 -07:00
u32 newI = this - > recentMenu - > addItem ( path_ws . c_str ( ) , this - > uic_file_recent_next ) ;
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
std : : cerr < < " +this->recentMenu->addItem "
< < " idx: " < < newI
< < " commandID: " < < this - > uic_file_recent_next
< < std : : endl ;
}
2021-03-20 22:42:48 -07:00
// IGUIContextMenu* menu = this->recentMenu->getSubMenu(newI);
2021-03-22 09:55:24 -07:00
// NOTE: Caller would be the parent menu id on click!
// newI is a sequential number starting at 1 which becomes the
// selected item (See menu->getSelectedItem() in handleMenuItemPressed)
2021-03-29 10:54:27 -07:00
// this->recentIndices.push_back(newI);
this - > recentIndices . push_back ( this - > uic_file_recent_next ) ;
2021-03-22 07:38:02 -07:00
this - > uic_file_recent_next + + ;
2021-02-18 06:31:03 -08:00
/*
if ( this - > m_file_recent_first_idx < 0 ) {
this - > m_file_recent_first_idx = menu - > getID ( ) ; // SIGSEGV crash
}
this - > m_file_recent_last_idx = menu - > getID ( ) ;
*/
2021-03-28 05:50:51 -07:00
if ( addToEngine ) {
this - > m_Engine - > addRecent ( path ) ;
}
2021-02-18 06:31:03 -08:00
}
}
2021-03-20 22:42:48 -07:00
void UserInterface : : addRecentMenuItems ( std : : vector < std : : string > paths , bool addToEngine )
2021-02-18 06:31:03 -08:00
{
2021-03-20 22:42:48 -07:00
if ( ! this - > recent_initialized ) {
2021-03-22 05:32:53 -07:00
throw std : : runtime_error ( " The UI is not ready in addRecent. " ) ;
2021-03-20 22:42:48 -07:00
}
2021-02-18 06:31:03 -08:00
for ( std : : vector < std : : string > : : iterator it = paths . begin ( ) ; it ! = paths . end ( ) ; + + it ) {
2021-03-22 05:32:53 -07:00
try {
this - > addRecentMenuItem ( * it , addToEngine ) ;
}
catch ( const std : : runtime_error & ex ) {
2021-03-22 07:38:02 -07:00
cerr < < ex . what ( ) < < std : : endl ;
2021-03-22 05:32:53 -07:00
break ;
}
2021-02-18 06:31:03 -08:00
}
}
bool UserInterface : : hasRecent ( std : : string path )
{
2021-11-28 13:17:17 -08:00
bool enableVerbose = false ;
if ( this - > m_Engine ! = nullptr ) {
enableVerbose = this - > m_Engine - > m_EnableVerbose ;
} else {
std : : cerr < < " Error: The engine is not ready in hasRecent. " < < std : : endl ;
}
2021-03-20 22:42:48 -07:00
if ( ! this - > recent_initialized ) {
2021-03-22 05:32:53 -07:00
throw std : : runtime_error ( " The UI is not ready in addRecent. " ) ;
2021-03-20 22:42:48 -07:00
}
2021-11-28 13:17:17 -08:00
if ( enableVerbose ) {
std : : cerr < < " [hasRecent] " < < std : : endl ;
std : : cerr < < " * checking children... " < < std : : endl ;
}
2021-03-29 10:54:27 -07:00
// See http://irrlicht.sourceforge.net/docu/_i_g_u_i_element_8h_source.html#l00570
// core::list< IGUIElement * > Children = this->getChildren();
// ^ ‘ class UserInterface’ has no member named ‘ getChildren’
// core::list< IGUIElement * > Children = this->recentMenu->getChildren();
// ^ gets no results
// core::list< IGUIElement * > Children = this->menu->getChildren();
// ^ only gets UIE_FILEMENU, UIE_PLAYBACKMENU, and UIE_VIEWMENU
std : : string thisItemStr = " " ;
for ( u32 i = 0 ; i < this - > recentMenu - > getItemCount ( ) ; i + + ) {
thisItemStr = Utility : : toString ( ( wstring ) this - > recentMenu - > getItemText ( i ) ) ;
// getItemText gets wchar_t*
// std::cerr << " * text:" << thisItemStr
// << std::endl;
if ( thisItemStr = = path )
return true ;
}
return false ;
// The commented section below is not valid since there are no children
// apparently, only items (inaccessible internals obtained by index).
/*
core : : list < IGUIElement * > Children = this - > recentMenu - > getChildren ( ) ;
core : : list < IGUIElement * > : : Iterator it = Children . begin ( ) ;
for ( ; it ! = Children . end ( ) ; + + it )
{
irr : : gui : : IGUIElement * child = * it ;
std : : cerr < < " * text: " < < Utility : : toString ( ( std : : wstring ) child - > getText ( ) )
< < " parent: " < < Utility : : toString ( ( std : : wstring ) child - > getParent ( ) - > getText ( ) )
< < " id: " < < Utility : : toString ( child - > getID ( ) )
< < std : : endl ;
// - getText is a const wchar_t*
// - getParent is an IGUIElement*
// (*it)->Parent;
}
// ^ gets no results
std : : cerr < < " * checking recent menu items for " < < path < < " ... " < < std : : endl ;
2021-02-18 06:31:03 -08:00
for ( std : : vector < u32 > : : iterator uiIt = this - > recentIndices . begin ( ) ; uiIt ! = this - > recentIndices . end ( ) ; + + uiIt ) {
2021-03-29 10:54:27 -07:00
// In the comments below, 1 is selected (idx) and 1101 is commandID.
// None of the commands work! An item is not an IGUI element apparently!
// IGUIContextMenu* child = this->recentMenu->getSubMenu(*uiIt);
// ^ null for 1 or 1101
// irr::gui::IGUIElement* child = this->recentMenu->getElementFromId(*uiIt, true);
// ^ null for 1101
// irr::gui::IGUIElement* child = this->menu->getElementFromId(*uiIt, true);
// ^ null for 1 or 1101
// irr::gui::IGUIElement* child = this->recentMenu->getElementFromId(*uiIt, true);
// ^ null for 1 or 1101
irr : : gui : : IGUIElement * child = this - > getGUIEnvironment ( ) - > getRootGUIElement ( ) - > getElementFromId ( 1 , true ) ;
// ^ null for 1 or 1101
// ^ cast to the specific IGUI... interface before use!
// ^ See <http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=29322>
if ( child ! = nullptr ) {
std : : cerr < < " - " < < * uiIt < < " (1): " < < Utility : : toString ( child - > getText ( ) ) < < std : : endl ;
if ( Utility : : toString ( child - > getText ( ) ) = = path ) {
2021-03-20 22:42:48 -07:00
return true ;
}
}
else {
2021-03-29 10:54:27 -07:00
std : : cerr < < " - null at " < < * uiIt < < std : : endl ;
2021-03-22 07:38:02 -07:00
std : : string uiItMsg = std : : to_string ( * uiIt ) ;
// std::string uiItMsg = "<bad uiIt value in recentIndices: ";
// try {
// uiItMsg += std::to_string(*uiIt);
// }
// catch (const std::invalid_argument& ex) {
// uiItMsg += ex.what();
// }
// uiItMsg += ">";
2021-03-29 10:54:27 -07:00
const std : : string msg = " There was no child for " + uiItMsg + " in hasRecent " ;
cerr < < " " < < msg < < endl ;
2021-03-22 05:32:53 -07:00
throw std : : runtime_error ( msg ) ;
2021-02-18 06:31:03 -08:00
}
}
2021-03-29 10:54:27 -07:00
*/
2021-02-18 06:31:03 -08:00
return false ;
}
2021-03-29 10:54:27 -07:00
bool UserInterface : : openRecent ( s32 commandID , s32 selectedItemID )
2021-02-18 06:31:03 -08:00
{
2021-03-22 16:34:34 -07:00
bool result = false ;
2021-03-20 22:42:48 -07:00
if ( ! this - > recent_initialized ) {
2021-03-28 03:56:19 -07:00
throw std : : runtime_error ( " The UI is not ready in openRecent. " ) ;
2021-03-20 22:42:48 -07:00
}
2021-03-22 16:34:34 -07:00
// IGUIElement* submenu = this->recentMenu->getElementFromId(commandID);
// ^ There is no element for menuID (such as 1100) nor for commandID (such as 1)
// IGUIElement* submenu = this->recentMenu->getSubMenu(selectedItemID);
// ^ There is no submenu for selectedItemID (such as 1)
// IGUIElement* submenu = this->recentMenu->getSubMenu(commandID);
// ^ There is no submenu for commandID (such as 1101)
// IGUIElement* submenu = this->menu->getElementFromId(commandID);
// ^ There is no elemend for commandID (such as 1101)
// IGUIElement* submenu = this->menu->getElementFromId(selectedItemID);
// ^ There is no element for selectedItemID (such as 1)
// IGUIElement* submenu = this->menu->getSubMenu(commandID);
// ^ There is no submenu for commandID (such as 1101)
IGUIElement * submenu = this - > menu - > getSubMenu ( selectedItemID ) ;
2021-03-29 10:54:27 -07:00
// ^ requires the sequential selectedItemID (NOT commandID specified on create)
2021-03-22 16:34:34 -07:00
if ( submenu ! = nullptr ) {
std : : wstring menuText = this - > recentMenu - > getItemText ( selectedItemID ) ;
// std::string path = Utility::toString(submenu->getText());
// ^ blank
std : : string path = Utility : : toString ( menuText ) ; // blank
cerr < < " path: " < < path < < endl ;
cerr < < " selectedItemID: " < < selectedItemID < < endl ;
cerr < < " menuText: " < < Utility : : toString ( menuText ) < < endl ;
2021-03-29 10:54:27 -07:00
result = m_Engine - > loadMesh ( menuText , true ) ; // true to adjust recent menu order
2021-03-22 16:34:34 -07:00
if ( ! result ) {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Load Mesh " , L " The model is inaccessible or not in a compatible format. " ) ;
}
}
else {
cerr < < " [UserInterface::openRecent] Error: There is no submenu for selectedItemID " < < selectedItemID < < std : : endl ;
// for (auto it : this->recentMenu->getChildren()) {
// cerr << " - " << it << std::endl;
// }
// ^ iterates 0 times; ranged for
}
return result ;
2021-02-18 06:31:03 -08:00
}
2010-04-21 07:48:36 -07:00
// IEventReceiver
2019-04-11 01:31:04 -07:00
bool UserInterface : : OnEvent ( const SEvent & event )
2010-04-21 07:48:36 -07:00
{
2021-03-22 09:21:01 -07:00
// Note EventHandler::OnEvent calls other handlers for
// Certain event types (See ERT_3DVIEW there for instance).
2019-04-19 12:29:30 -07:00
bool handled = false ;
2019-04-11 01:31:04 -07:00
if ( event . EventType = = EET_USER_EVENT ) {
2019-04-19 12:29:30 -07:00
// debug() << "EET_USER_EVENT..." << endl;
2019-04-11 01:31:04 -07:00
if ( event . UserEvent . UserData1 = = UEI_WINDOWSIZECHANGED ) {
2019-04-19 14:13:58 -07:00
if ( ( m_WindowSize . Width ! = m_Engine - > m_Driver - > getScreenSize ( ) . Width )
| | ( m_WindowSize . Height ! = m_Engine - > m_Driver - > getScreenSize ( ) . Height ) ) {
2019-04-11 01:31:04 -07:00
snapWidgets ( ) ;
}
2019-04-19 12:29:30 -07:00
handled = true ;
}
} else if ( event . EventType = = EET_GUI_EVENT ) {
// debug() << "EET_GUI_EVENT..." << endl;
handled = true ; // set to false below if not handled
const SEvent : : SGUIEvent * ge = & ( event . GUIEvent ) ;
2021-02-18 06:31:03 -08:00
s32 callerID = ge - > Caller - > getID ( ) ;
2021-03-22 08:22:21 -07:00
switch ( ge - > EventType ) {
// See http://irrlicht.sourceforge.net/docu/example009.html
case EGET_BUTTON_CLICKED :
switch ( callerID ) {
case UIE_PLAYBACKSTARTSTOPBUTTON :
this - > m_Engine - > toggleAnimation ( ) ;
break ;
case UIE_PLAYBACKINCREASEBUTTON :
this - > m_Engine - > incrementAnimationFPS ( 5 ) ;
break ;
case UIE_PLAYBACKDECREASEBUTTON :
this - > m_Engine - > incrementAnimationFPS ( - 5 ) ;
break ;
default :
cerr < < " EGET_BUTTON_CLICKED wasn't expected from ID " < < callerID < < std : : endl ;
handled = false ;
break ;
2019-05-16 09:33:53 -07:00
}
2021-03-22 08:22:21 -07:00
case EGET_FILE_SELECTED :
2021-03-22 09:21:01 -07:00
this - > m_Engine - > m_View - > m_MouseUser = " " ;
2021-03-22 08:22:21 -07:00
switch ( callerID ) {
case UIE_LOADFILEDIALOG :
{
IGUIFileOpenDialog * fileOpenDialog = static_cast < IGUIFileOpenDialog * > ( ge - > Caller ) ;
wstring path = fileOpenDialog - > getFileName ( ) ;
bool result = false ;
wstring extension = Utility : : extensionOf ( path ) ;
if ( Utility : : toLower ( Utility : : toString ( extension ) ) = = " irr " ) {
result = m_Engine - > loadScene ( fileOpenDialog - > getFileName ( ) ) ;
}
else {
2021-03-29 10:54:27 -07:00
result = m_Engine - > loadMesh ( fileOpenDialog - > getFileName ( ) , true ) ;
2021-03-22 08:22:21 -07:00
}
if ( result ) {
try {
2021-02-18 06:31:03 -08:00
2021-03-22 08:22:21 -07:00
this - > addRecentMenuItem ( Utility : : toString ( path ) , true ) ;
}
catch ( const std : : runtime_error & ex ) {
cerr < < ex . what ( ) < < std : : endl ;
break ;
}
}
if ( ! result ) {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Load Mesh " , L " The model is inaccessible or not in a compatible format. " ) ;
}
2021-03-22 05:32:53 -07:00
}
2019-06-13 05:57:32 -07:00
2021-03-22 08:22:21 -07:00
break ;
case UIE_SAVEFILEDIALOG :
{
if ( m_Engine - > m_LoadedMesh ! = nullptr ) {
IGUIFileOpenDialog * fileOpenDialog = static_cast < IGUIFileOpenDialog * > ( ge - > Caller ) ;
// fileOpenDialog->getFileName()
m_Engine - > saveMesh ( fileOpenDialog - > getDirectoryName ( ) , " " , " dae " ) ;
}
else {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Export " , L " There is nothing to save. " ) ;
}
}
break ;
case UIE_LOADTEXTUREDIALOG :
{
IGUIFileOpenDialog * fileOpenDialog = static_cast < IGUIFileOpenDialog * > ( ge - > Caller ) ;
2021-03-29 11:10:40 -07:00
m_Engine - > loadTexture ( fileOpenDialog - > getFileName ( ) , true ) ;
2021-03-22 08:22:21 -07:00
}
break ;
default :
cerr < < " EGET_FILE_SELECTED wasn't expected from ID: " < < callerID < < std : : endl ;
handled = false ;
break ;
2019-04-19 12:29:30 -07:00
}
2021-03-22 08:22:21 -07:00
case EGET_EDITBOX_ENTER :
switch ( callerID ) {
case UIE_PLAYBACKSETFRAMEEDITBOX :
if ( this - > m_Engine - > m_LoadedMesh ! = nullptr ) {
this - > m_Engine - > m_LoadedMesh - > setCurrentFrame (
Utility : : toF32 ( this - > playbackSetFrameEditBox - > getText ( ) )
) ;
}
break ;
case UIE_PLAYBACKSTARTFRAMEEDITBOX :
if ( this - > m_Engine - > m_LoadedMesh ! = nullptr ) {
this - > m_Engine - > m_LoadedMesh - > setFrameLoop (
Utility : : toF32 ( this - > playbackStartFrameEditBox - > getText ( ) ) ,
Utility : : toF32 ( this - > playbackEndFrameEditBox - > getText ( ) )
) ;
}
break ;
case UIE_PLAYBACKENDFRAMEEDITBOX :
if ( this - > m_Engine - > m_LoadedMesh ! = nullptr ) {
this - > m_Engine - > m_LoadedMesh - > setFrameLoop (
Utility : : toF32 ( this - > playbackStartFrameEditBox - > getText ( ) ) ,
Utility : : toF32 ( this - > playbackEndFrameEditBox - > getText ( ) )
) ;
}
break ;
case UIE_TEXTUREPATHEDITBOX :
if ( this - > m_Engine - > m_LoadedMesh ! = nullptr ) {
2021-03-29 11:10:40 -07:00
this - > m_Engine - > loadTexture ( texturePathEditBox - > getText ( ) , false ) ;
2021-03-22 08:22:21 -07:00
}
break ;
case UIE_FPSEDITBOX :
if ( this - > m_Engine - > m_LoadedMesh ! = nullptr ) {
this - > m_Engine - > m_LoadedMesh - > setAnimationSpeed (
Utility : : toF32 ( this - > playbackFPSEditBox - > getText ( ) )
) ;
}
break ;
case UIE_AXISSIZEEDITBOX :
this - > m_Engine - > m_AxisLength = Utility : : toF32 (
this - > axisSizeEditBox - > getText ( )
2019-04-19 14:13:58 -07:00
) ;
2021-03-22 08:22:21 -07:00
break ;
default :
cerr < < " EGET_EDITBOX_ENTER isn't processed for ID: " < < callerID < < std : : endl ;
handled = false ;
break ;
2019-04-19 12:29:30 -07:00
}
2021-03-22 09:21:01 -07:00
case EGET_MESSAGEBOX_YES :
this - > m_Engine - > m_View - > m_MouseUser = " " ;
break ;
case EGET_MESSAGEBOX_NO :
this - > m_Engine - > m_View - > m_MouseUser = " " ;
break ;
case EGET_MESSAGEBOX_OK :
this - > m_Engine - > m_View - > m_MouseUser = " " ;
break ;
case EGET_MESSAGEBOX_CANCEL :
this - > m_Engine - > m_View - > m_MouseUser = " " ;
break ;
case EGET_FILE_CHOOSE_DIALOG_CANCELLED :
// ^ 12 usually
this - > m_Engine - > m_View - > m_MouseUser = " " ;
break ;
case EGET_ELEMENT_FOCUS_LOST :
// ^ 0 usually
switch ( callerID ) {
case UIE_LOADFILEDIALOG :
this - > m_Engine - > m_View - > m_MouseUser = " " ;
break ;
case UIE_SAVEFILEDIALOG :
this - > m_Engine - > m_View - > m_MouseUser = " " ;
break ;
default :
break ;
}
debug ( ) < < callerID < < " lost focus. " < < std : : endl ;
handled = false ;
break ;
case EGET_ELEMENT_FOCUSED :
switch ( callerID ) {
case UIE_LOADFILEDIALOG :
this - > m_Engine - > m_View - > m_MouseUser = " UIE_LOADFILEDIALOG " ;
break ;
case UIE_SAVEFILEDIALOG :
this - > m_Engine - > m_View - > m_MouseUser = " UIE_SAVEFILEDIALOG " ;
break ;
default :
break ;
}
debug ( ) < < callerID < < " got focus. " < < std : : endl ;
handled = false ;
break ;
case EGET_ELEMENT_HOVERED :
2021-03-29 10:54:27 -07:00
// debug() << "hovered over " << callerID << "." << std::endl;
2021-03-22 09:21:01 -07:00
handled = false ;
break ;
case EGET_ELEMENT_LEFT :
2021-11-28 13:17:17 -08:00
// debug() << "left " << callerID << "." << std::endl;
2021-03-22 09:21:01 -07:00
handled = false ;
break ;
case EGET_MENU_ITEM_SELECTED :
handled = handleMenuItemPressed ( ge ) ;
break ;
case EGET_SCROLL_BAR_CHANGED :
handled = false ;
break ;
case EGET_COMBO_BOX_CHANGED :
handled = false ;
break ;
case EGET_ELEMENT_CLOSED :
debug ( ) < < " closed " < < callerID < < " . " < < std : : endl ;
handled = false ;
break ;
case EGET_DIRECTORY_SELECTED :
this - > m_Engine - > m_View - > m_MouseUser = " " ;
handled = false ;
break ;
2021-03-29 10:54:27 -07:00
case EGET_EDITBOX_MARKING_CHANGED :
this - > m_Engine - > m_View - > m_MouseUser = " edit box " ;
handled = false ;
break ;
2021-03-22 08:22:21 -07:00
default :
// EET_MOUSE_INPUT_EVENT EET_KEY_INPUT_EVENT EET_JOYSTICK_INPUT_EVENT
2021-03-22 09:21:01 -07:00
cerr < < " [UserInterface] (verbose message) event.GUIEvent.EventType " < < ge - > EventType < < " (See EGET_* in irrlicht/IEventReciever.h) is not handled (event.EventType is EET_GUI_EVENT). " < < std : : endl ;
2021-02-18 06:31:03 -08:00
handled = false ;
2021-03-22 08:22:21 -07:00
break ;
2019-04-11 01:31:04 -07:00
}
2021-03-22 08:22:21 -07:00
2019-04-11 01:31:04 -07:00
} else if ( event . EventType = = EET_KEY_INPUT_EVENT ) {
2019-04-19 12:29:30 -07:00
// debug() << "EET_KEY_INPUT_EVENT..." << endl;
handled = true ; // set to false below if not handled
2019-04-19 14:16:28 -07:00
if ( event . KeyInput . PressedDown
& & ! m_Engine - > KeyIsDown [ event . KeyInput . Key ] ) {
2019-03-10 06:55:31 -07:00
if ( event . KeyInput . Key = = irr : : KEY_F5 ) {
2019-04-19 14:13:58 -07:00
if ( m_Engine - > KeyIsDown [ irr : : KEY_LSHIFT ]
| | m_Engine - > KeyIsDown [ irr : : KEY_RSHIFT ] ) {
2021-03-29 10:54:27 -07:00
bool result = m_Engine - > reloadTexture ( ) ;
if ( ! result ) {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Reload Texture " , L " The texture is inaccessible or not in a compatible format. " ) ;
}
2019-04-19 12:29:30 -07:00
}
2019-05-16 09:33:53 -07:00
else {
2020-03-10 11:12:16 -07:00
if ( m_Engine - > m_LoadedMeshPath . length ( ) > 0 ) {
2019-05-16 09:33:53 -07:00
bool result = m_Engine - > reloadMesh ( ) ;
if ( ! result ) {
this - > m_Engine - > m_Device - > getGUIEnvironment ( ) - > addMessageBox (
L " Reload Mesh " , L " The model is inaccessible or not in a compatible format. " ) ;
}
}
else {
debug ( ) < < " - No mesh is loaded. " < < endl ;
}
}
2019-04-19 12:29:30 -07:00
} else if ( event . KeyInput . Key = = irr : : KEY_F3 ) {
2019-04-19 14:13:58 -07:00
if ( m_Engine - > KeyIsDown [ irr : : KEY_LSHIFT ]
| | m_Engine - > KeyIsDown [ irr : : KEY_RSHIFT ] ) {
2019-04-19 12:29:30 -07:00
loadNextTexture ( - 1 ) ;
debug ( ) < < " - back " < < endl ;
}
else
loadNextTexture ( 1 ) ;
} else if ( event . KeyInput . Key = = irr : : KEY_KEY_I ) {
2019-04-19 14:13:58 -07:00
if ( m_Engine - > KeyIsDown [ irr : : KEY_LCONTROL ]
| | m_Engine - > KeyIsDown [ irr : : KEY_RCONTROL ] ) {
// IGUIContextMenu* textureInterpolationElement = (
// dynamic_cast<IGUIContextMenu*>(
// viewMenu->getElementFromId(
// UIC_VIEW_TEXTURE_INTERPOLATION
// )
// );
// )
2019-07-03 12:15:44 -07:00
m_Engine - > setEnableTextureInterpolation (
! m_Engine - > getEnableTextureInterpolation ( )
) ;
viewMenu - > setItemChecked (
viewTextureInterpolationIdx ,
m_Engine - > getEnableTextureInterpolation ( )
) ;
2019-04-19 12:29:30 -07:00
}
else
handled = false ;
} else if ( event . KeyInput . Key = = irr : : KEY_RIGHT ) {
2019-04-19 14:13:58 -07:00
if ( m_Engine - > KeyIsDown [ irr : : KEY_LCONTROL ]
| | m_Engine - > KeyIsDown [ irr : : KEY_RCONTROL ] ) {
2019-04-19 12:29:30 -07:00
m_Engine - > incrementAnimationFPS ( 5 ) ;
2019-03-07 21:52:29 -08:00
}
2019-06-13 05:57:32 -07:00
else {
incrementFrame ( 1.0f , true ) ;
}
2019-04-19 12:29:30 -07:00
} else if ( event . KeyInput . Key = = irr : : KEY_LEFT ) {
2019-04-19 14:13:58 -07:00
if ( m_Engine - > KeyIsDown [ irr : : KEY_LCONTROL ]
| | m_Engine - > KeyIsDown [ irr : : KEY_RCONTROL ] ) {
2019-04-19 12:29:30 -07:00
m_Engine - > incrementAnimationFPS ( - 5 ) ;
}
2019-06-13 05:57:32 -07:00
else {
incrementFrame ( - 1.0f , true ) ;
}
2019-04-11 01:31:04 -07:00
} else if ( event . KeyInput . Char = = L ' ' ) {
2019-03-07 21:52:29 -08:00
m_Engine - > toggleAnimation ( ) ;
2019-04-03 07:35:27 -07:00
}
2019-04-19 12:29:30 -07:00
else
handled = false ;
2019-03-07 21:52:29 -08:00
// std::wcerr << "Char: " << event.KeyInput.Char << endl;
}
2019-03-10 06:55:31 -07:00
m_Engine - > KeyIsDown [ event . KeyInput . Key ] = event . KeyInput . PressedDown ;
2019-03-07 21:52:29 -08:00
return true ;
2019-04-11 01:31:04 -07:00
} else if ( event . EventType = = EET_MOUSE_INPUT_EVENT ) {
2019-04-19 12:29:30 -07:00
// debug() << "EET_MOUSE_INPUT_EVENT..." << endl;
handled = true ; // set to false below if not handled
// TODO: improve this copypasta (or elsewhere use states 1 and 3 as
// events, and add 1 as "handled" (or set back to 0 for no drag feature)
// as intended for drag or long press handling).
2019-04-11 01:31:04 -07:00
switch ( event . MouseInput . Event ) {
2019-03-09 05:56:23 -08:00
case EMIE_LMOUSE_LEFT_UP :
2019-04-11 01:31:04 -07:00
if ( m_Engine - > LMouseState = = 2 ) {
2019-03-10 06:55:31 -07:00
m_Engine - > LMouseState = 3 ;
2019-03-09 05:56:23 -08:00
}
break ;
case EMIE_LMOUSE_PRESSED_DOWN :
2019-04-11 01:31:04 -07:00
if ( m_Engine - > LMouseState = = 0 ) {
2019-03-10 06:55:31 -07:00
m_Engine - > LMouseState = 1 ;
2019-03-09 05:56:23 -08:00
}
break ;
case EMIE_RMOUSE_LEFT_UP :
2019-04-11 01:31:04 -07:00
if ( m_Engine - > RMouseState = = 2 ) {
2019-03-10 06:55:31 -07:00
m_Engine - > RMouseState = 3 ;
2019-03-09 05:56:23 -08:00
}
break ;
case EMIE_RMOUSE_PRESSED_DOWN :
2019-04-11 01:31:04 -07:00
if ( m_Engine - > RMouseState = = 0 ) {
2019-03-10 06:55:31 -07:00
m_Engine - > RMouseState = 1 ;
2019-03-09 05:56:23 -08:00
}
break ;
2019-04-19 12:29:30 -07:00
default :
handled = false ;
2019-03-09 05:56:23 -08:00
}
2021-03-22 08:22:21 -07:00
} else {
cerr < < " [UserInterface] (verbose message) event.EventType " < < event . EventType < < " is ignored. " < < std : : endl ;
2010-04-21 07:48:36 -07:00
}
2019-04-19 12:29:30 -07:00
return handled ;
2010-04-21 07:48:36 -07:00
}