diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index e9965e0f1..ce60d7f42 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -234,10 +234,6 @@ CDriverGL::CDriverGL() _CursorScale = 1.f; _MouseCaptured = false; -#if defined(NL_OS_WINDOWS) - _BorderlessFullscreen = false; -#endif - _NeedToRestaureGammaRamp = false; _win = EmptyWindow; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index fb6069447..c4540b9da 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -996,12 +996,6 @@ private: EWindowStyle getWindowStyle() const; bool setWindowStyle(EWindowStyle windowStyle); -#if defined(NL_OS_WINDOWS) - static BOOL CALLBACK monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData); - bool _BorderlessFullscreen; -#endif - std::string _CurrentDisplayDevice; - // Methods to manage screen resolutions bool restoreScreenMode(); bool saveScreenMode(); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp index 4e08884b0..751e72149 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_window.cpp @@ -1271,86 +1271,10 @@ static sint modeInfoToFrequency(XF86VidModeModeInfo *info) // *************************************************************************** -#if defined(NL_OS_WINDOWS) - -struct CMonitorEnumParams -{ -public: - CDriverGL *Driver; - const char *DeviceName; - bool Success; -}; - -BOOL CALLBACK CDriverGL::monitorEnumProcFullscreen(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) -{ - CMonitorEnumParams *p = reinterpret_cast(dwData); - - MONITORINFOEXA monitorInfo; - memset(&monitorInfo, 0, sizeof(monitorInfo)); - monitorInfo.cbSize = sizeof(monitorInfo); - GetMonitorInfoA(hMonitor, &monitorInfo); - nldebug("3D: Monitor: '%s'", monitorInfo.szDevice); - - size_t devLen = strlen(monitorInfo.szDevice); - size_t targetLen = strlen(p->DeviceName); - - nlassert(devLen < 32); - size_t minLen = min(devLen, targetLen); - if (!memcmp(monitorInfo.szDevice, p->DeviceName, minLen)) - { - if (devLen == targetLen - || (devLen < targetLen && (p->DeviceName[minLen] == '\\')) - || (devLen > targetLen && (monitorInfo.szDevice[minLen] == '\\'))) - { - nldebug("3D: Remapping '%s' to '%s'", p->DeviceName, monitorInfo.szDevice); - nldebug("3D: Found requested monitor at %i, %i", monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top); - p->Driver->_CurrentMode.Windowed = false; - p->Driver->setWindowStyle(CDriverGL::EWSWindowed); - p->Driver->setWindowSize(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top); - LONG dwStyle = GetWindowLong(p->Driver->_win, GWL_STYLE); - SetWindowLong(p->Driver->_win, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); - SetWindowPos(p->Driver->_win, NULL, - monitorInfo.rcMonitor.left, - monitorInfo.rcMonitor.top, - monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, - monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top, - SWP_FRAMECHANGED); - p->Driver->_WindowX = monitorInfo.rcMonitor.left; - p->Driver->_WindowY = monitorInfo.rcMonitor.top; - p->Driver->_CurrentDisplayDevice = std::string(p->DeviceName); - p->Driver->_BorderlessFullscreen = true; - p->Driver->_CurrentMode.Windowed = false; - p->Success = true; - return FALSE; - } - } - p->Success = false; - return TRUE; // continue -}; - -#endif - -// *************************************************************************** - bool CDriverGL::setScreenMode(const GfxMode &mode) { H_AUTO_OGL(CDriverGL_setScreenMode) - nldebug("3D: setScreenMode"); - -#if defined(NL_OS_WINDOWS) - if (_BorderlessFullscreen) - { - _BorderlessFullscreen = false; - LONG dwStyle = GetWindowLong(_win, GWL_STYLE); - dwStyle |= WS_OVERLAPPEDWINDOW; - if (!_Resizable) dwStyle ^= WS_MAXIMIZEBOX|WS_THICKFRAME; - SetWindowLong(_win, GWL_STYLE, dwStyle); - SetWindowPos(_win, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); - _CurrentMode.Windowed = true; - } -#endif - if (mode.Windowed) { // if fullscreen, switch back to desktop screen mode @@ -1360,17 +1284,13 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) return true; } - if (_CurrentDisplayDevice != mode.DisplayDevice) - restoreScreenMode(); - // save previous screen mode only if switching from windowed to fullscreen if (_CurrentMode.Windowed) saveScreenMode(); // if switching exactly to the same screen mode, doesn't change it GfxMode previousMode; - if (_CurrentDisplayDevice == mode.DisplayDevice - && getCurrentScreenMode(previousMode) + if (getCurrentScreenMode(previousMode) && mode.Width == previousMode.Width && mode.Height == previousMode.Height && mode.Depth == previousMode.Depth @@ -1379,9 +1299,7 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) #if defined(NL_OS_WINDOWS) - const char *deviceName = mode.DisplayDevice.c_str(); - - DEVMODEA devMode; + DEVMODE devMode; memset(&devMode, 0, sizeof(DEVMODE)); devMode.dmSize = sizeof(DEVMODE); devMode.dmDriverExtra = 0; @@ -1389,42 +1307,22 @@ bool CDriverGL::setScreenMode(const GfxMode &mode) devMode.dmPelsWidth = mode.Width; devMode.dmPelsHeight = mode.Height; - if (mode.Depth > 0) + if(mode.Depth > 0) { devMode.dmBitsPerPel = mode.Depth; devMode.dmFields |= DM_BITSPERPEL; } - if (mode.Frequency > 0) + if(mode.Frequency > 0) { devMode.dmDisplayFrequency = mode.Frequency; devMode.dmFields |= DM_DISPLAYFREQUENCY; } - - if (deviceName[0]) + + if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { - // First attempt exclusive fullscreen - nldebug("3D: ChangeDisplaySettingsEx"); - LONG resex; - if ((resex = ChangeDisplaySettingsExA(deviceName, &devMode, NULL, CDS_FULLSCREEN, NULL)) != DISP_CHANGE_SUCCESSFUL) - { - nlwarning("3D: Fullscreen mode switch failed (%i)", (sint)resex); - // Workaround, resize to monitor and make borderless - CMonitorEnumParams p; - p.DeviceName = deviceName; - p.Driver = this; - EnumDisplayMonitors(NULL, NULL, monitorEnumProcFullscreen, (LPARAM)&p); - return p.Success; - } - } - else - { - nldebug("3D: ChangeDisplaySettings"); - if (ChangeDisplaySettingsA(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) - { - nlwarning("3D: Fullscreen mode switch failed"); - return false; - } + nlwarning("3D: Fullscreen mode switch failed"); + return false; } #elif defined(NL_OS_MAC) @@ -1830,11 +1728,7 @@ bool CDriverGL::setWindowStyle(EWindowStyle windowStyle) dwNewStyle |= WS_VISIBLE; if (dwStyle != dwNewStyle) - { SetWindowLong(_win, GWL_STYLE, dwNewStyle); - if (windowStyle == EWSWindowed) - SetWindowPos(_win, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); - } // if (windowStyle == EWSMaximized && isVisible && !isMaximized) // ShowWindow(_hWnd, SW_SHOWMAXIMIZED); @@ -1962,24 +1856,19 @@ bool CDriverGL::setMode(const GfxMode& mode) && ScreenToClient(_win, &cursorPos); sint curX = (sint)cursorPos.x * (sint)mode.Width; sint curY = (sint)cursorPos.y * (sint)mode.Height; - if (_BorderlessFullscreen) - ReleaseCapture(); #endif if (!setScreenMode(mode)) return false; - if (!_BorderlessFullscreen) - { - // when changing window style, it's possible system change window size too - setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); + // when changing window style, it's possible system change window size too + setWindowStyle(mode.Windowed ? EWSWindowed : EWSFullscreen); - if (!mode.Windowed) - _CurrentMode.Depth = mode.Depth; + if (!mode.Windowed) + _CurrentMode.Depth = mode.Depth; - setWindowSize(mode.Width, mode.Height); - setWindowPos(_WindowX, _WindowY); - } + setWindowSize(mode.Width, mode.Height); + setWindowPos(_WindowX, _WindowY); switch (_CurrentMode.Depth) { @@ -1996,8 +1885,6 @@ bool CDriverGL::setMode(const GfxMode& mode) cursorPos.y = curY / (sint)mode.Height; ClientToScreen(_win, &cursorPos); SetCursorPos(cursorPos.x, cursorPos.y); - if (_BorderlessFullscreen) - SetCapture(_win); } #endif diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_assets_ps_batched.ms b/code/nel/tools/3d/plugin_max/scripts/nel_assets_ps_batched.ms new file mode 100644 index 000000000..f8165e25e --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_assets_ps_batched.ms @@ -0,0 +1,378 @@ + +NEL3D_APPDATA_INTERFACE_FILE = 1423062700 + +-- Allocate 20 Me for the script +heapSize += 15000000 + +nlErrorFilename = "W:/database/conversion.log" +nlErrorStream = openFile nlErrorFilename mode:"w" +if nlErrorStream == undefined then + nlErrorStream = createFile nlErrorFilename + +-- Log a message +fn nllog message = +( + if nlErrorStream != undefined then + ( + format "%\n" message to:nlErrorStream + flush nlErrorStream + ) + + -- To the console + print message +) + +include "nel_utility.ms" + +fn findFile dir fileName = +( + if (doesFileExist (dir + "\\" + fileName)) then + ( + return (dir + "\\" + fileName) + ) + + dirArr = GetDirectories (dir + "\\*") + + for d in dirArr do + ( + local fileFound = findFile d fileName + if (fileFound != "") then + return fileFound + ) + + return "" +) + +fn getFixedPath ps = +( + if not (doesFileExist ps) then + ( + local fileName = filenameFromPath ps + local fileFound = findFile "W:\\database\\sfx" fileName + if (fileFound != "") then + return fileFound + else + return fileName + ) + else + ( + return ps + ) +) + +fn renameParticleSystem ps = +( + local newFileName = getFixedPath ps.ps_file_name + if (newFileName != ps.ps_file_name) then + ( + ps.ps_file_name = newFileName + return 1 + ) + else + ( + return 0 + ) +) + + +rollout assets_ps_rollout "Properties" +( + fn do_it = + ( + local result = 0 + + for m in getClassInstances nel_ps do + ( + if (renameParticleSystem m) == 1 then + result = 1 + ) + + max select none + + actionMan.executeAction 0 "40021" -- Selection: Select All + actionMan.executeAction 0 "311" -- Tools: Zoom Extents All Selected + actionMan.executeAction 0 "40807" -- Views: Activate All Maps + actionMan.executeAction 0 "63508" -- Views: Standard Display with Maps + actionMan.executeAction 0 "40043" -- Selection: Select None + + max views redraw + + return result + ) + + -- This script is a base script to include to add multiple functionality to your script + + -- To use this script + -- Include it in your script into the rollout at the beginning. + -- Implement a do_it function to do the job in your rollout. + -- The function should retun -1 if an arror occured, else the count of modification done + -- It the function returns <1, the project will not be overwritten + + Group "Running properties" + ( + RadioButtons SourceFiles "Source projects" labels:#("Current project", "All Projects in a folder") align:#left + + Label DirectoryLabel "Source directory" align:#left + EditText Directory "" width:500 align:#left enabled:false + Button BrowseDirectory "Browse..." align:#left enabled:false + + CheckBox Recurse "Look in subfolders" checked:true enabled:false + CheckBox Test "Test only, do not save" checked:false enabled:false + CheckBox BackupFiles "Backup files" checked:false enabled:false + CheckBox StopOnError "Stop on error" checked:false enabled:false + CheckBox UseTag "Use tag" checked:false enabled:false + + Label ProgressText width:500 align:#left + ProgressBar Progress width:500 align:#left + + Button GoButton "Go" width:500 align:#left + ) + + local countModifications + local countErrors + local fileModified + local fileParsed + + fn UpdateData = + ( + if SourceFiles.state == 2 then + isSourceDir = true + else + isSourceDir = false + if Test.checked == true then + isTest = true + else + isTest = false + + Directory.enabled = isSourceDir + BrowseDirectory.enabled = isSourceDir + Recurse.enabled = isSourceDir + Test.enabled = isSourceDir + BackupFiles.enabled = isSourceDir and (isTest == false) + StopOnError.enabled = isSourceDir + UseTag.enabled = isSourceDir + ) + + on SourceFiles changed state do + ( + UpdateData () + ) + + on Test changed state do + ( + UpdateData () + ) + + fn call_do_it = + ( + local result + + -- One more project + fileParsed = fileParsed + 1 + + -- Call it + result = do_it () + + -- Error ? + if result < 0 then + countErrors = countErrors + 1 + else + countModifications = countModifications + result + + -- Return result + return result + ) + + fn BackupFile file = + ( + local i + local newFilename + + i = 0 + while true do + ( + -- New file name + newFilename = file + ".backup_" + (i as string) + + -- File exist ? + if (fileExist newFilename) == false then + ( + if (copyFile file newFilename) == false then + return false + else + return true + ) + i = i + 1 + ) + ) + + fn RecurseFolder currentDirectory = + ( + resetMAXFile #noprompt + + local result + local file + local files + local origAnimStart + local origAnimEnd + local origFrameRate + + -- Parse files + files = getFiles (currentDirectory+"/*.max") + + -- For each files + for i = 1 to files.count do + ( + -- File name + file = files[i] + + -- Progress bar + ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" + Progress.value = i*100/files.count + + if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then + ( + resetMAXFile #noprompt + + nllog("CONVERT " + file) + + -- Open the max project + if loadMaxFile file quiet:true == true then + ( + objXRefMgr.UpdateAllRecords() + + result = call_do_it () + + -- Error ? + if result < 0 then + ( + if StopOnError.checked == true then + Messagebox ("Error in file " + file) + ) + else + ( + -- Save the max project ? + if (Test.checked == false) and (result != 0) then + ( + -- Backup the max project ? + local ok + ok = true + if BackupFiles.checked == true then + ( + -- Backup the file + if (BackupFile file) == false then + ( + -- Don't save the file because backup has failed + ok = false + + if StopOnError.checked == true then + Messagebox ("Can't backup file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + + -- Save the max project ? + if ok == true then + ( + if (saveMaxFile file) == true then + ( + fileModified = fileModified + 1 + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't write file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + ) + ) + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't load file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + else + ( + nllog("SKIP " + file + " by tag") + ) + ) + + -- Parse sub directory ? + if (Recurse.checked == true) then + ( + local directories + + -- Get the directories + directories = getDirectories (currentDirectory+"/*") + + -- For each directories + for dir in directories do + ( + RecurseFolder dir + ) + ) + ) + + on BrowseDirectory pressed do + ( + local dir + try + ( + dir = getSavePath () -- caption:"Select the projects directory" + if dir != undefined then + Directory.text = dir + ) + catch + ( + ) + ) + + on GoButton pressed do + ( + -- Reset count + countModifications = 0 + countErrors = 0 + fileModified = 0 + fileParsed = 0 + + -- Get files in the shape_source_directory + if SourceFiles.state == 2 then + ( + -- Should warning user ? + if (SourceFiles.state == 2) and (Test.checked == false) then + ( + -- Warning ! + if ((queryBox "Warning, all the files in the specified folders will be overwrited.\nYou should backup your files before executing this script.\nDo you want to continue executing this script ?" beep:true) == true) then + RecurseFolder (adjustPathStringForScript Directory.text) + ) + else + ( + RecurseFolder (adjustPathStringForScript Directory.text) + ) + ) + else + ( + -- Just compute the current project + call_do_it () + ) + + -- Show errors + ProgressText.text = (fileParsed as string) + " project(s) opened, " + (countModifications as string) + " project modification(s), " + (fileModified as string) + " project(s) saved, " + (countErrors as string) + " error(s)." + Progress.value = 100 + ) +) + +assets_ps_floater = newRolloutFloater "NeL Assets PS Database" 550 400 +addrollout assets_ps_rollout assets_ps_floater rolledUp:false + + diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave.ms b/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave.ms new file mode 100644 index 000000000..ab9e45325 --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave.ms @@ -0,0 +1,329 @@ + +NEL3D_APPDATA_INTERFACE_FILE = 1423062700 + +-- Allocate 20 Me for the script +heapSize += 15000000 + +nlErrorFilename = "W:/database/conversion.log" +nlErrorStream = openFile nlErrorFilename mode:"w" +if nlErrorStream == undefined then + nlErrorStream = createFile nlErrorFilename + +-- Log a message +fn nllog message = +( + if nlErrorStream != undefined then + ( + format "%\n" message to:nlErrorStream + flush nlErrorStream + ) + + -- To the console + print message +) + +include "nel_utility.ms" + +rollout assets_resave_rollout "Properties" +( + fn do_it = + ( + max select none + + actionMan.executeAction 0 "40021" -- Selection: Select All + actionMan.executeAction 0 "311" -- Tools: Zoom Extents All Selected + actionMan.executeAction 0 "40807" -- Views: Activate All Maps + actionMan.executeAction 0 "63508" -- Views: Standard Display with Maps + actionMan.executeAction 0 "40043" -- Selection: Select None + + max views redraw + + return 1 + ) + + -- This script is a base script to include to add multiple functionality to your script + + -- To use this script + -- Include it in your script into the rollout at the beginning. + -- Implement a do_it function to do the job in your rollout. + -- The function should retun -1 if an arror occured, else the count of modification done + -- It the function returns <1, the project will not be overwritten + + Group "Running properties" + ( + RadioButtons SourceFiles "Source projects" labels:#("Current project", "All Projects in a folder") align:#left + + Label DirectoryLabel "Source directory" align:#left + EditText Directory "" width:500 align:#left enabled:false + Button BrowseDirectory "Browse..." align:#left enabled:false + + CheckBox Recurse "Look in subfolders" checked:true enabled:false + CheckBox Test "Test only, do not save" checked:false enabled:false + CheckBox BackupFiles "Backup files" checked:false enabled:false + CheckBox StopOnError "Stop on error" checked:false enabled:false + CheckBox UseTag "Use tag" checked:false enabled:false + + Label ProgressText width:500 align:#left + ProgressBar Progress width:500 align:#left + + Button GoButton "Go" width:500 align:#left + ) + + local countModifications + local countErrors + local fileModified + local fileParsed + + fn UpdateData = + ( + if SourceFiles.state == 2 then + isSourceDir = true + else + isSourceDir = false + if Test.checked == true then + isTest = true + else + isTest = false + + Directory.enabled = isSourceDir + BrowseDirectory.enabled = isSourceDir + Recurse.enabled = isSourceDir + Test.enabled = isSourceDir + BackupFiles.enabled = isSourceDir and (isTest == false) + StopOnError.enabled = isSourceDir + UseTag.enabled = isSourceDir + ) + + on SourceFiles changed state do + ( + UpdateData () + ) + + on Test changed state do + ( + UpdateData () + ) + + fn call_do_it = + ( + local result + + -- One more project + fileParsed = fileParsed + 1 + + -- Call it + result = do_it () + + -- Error ? + if result < 0 then + countErrors = countErrors + 1 + else + countModifications = countModifications + result + + -- Return result + return result + ) + + fn BackupFile file = + ( + local i + local newFilename + + i = 0 + while true do + ( + -- New file name + newFilename = file + ".backup_" + (i as string) + + -- File exist ? + if (fileExist newFilename) == false then + ( + if (copyFile file newFilename) == false then + return false + else + return true + ) + i = i + 1 + ) + ) + + fn RecurseFolder currentDirectory = + ( + resetMAXFile #noprompt + + local result + local file + local files + local origAnimStart + local origAnimEnd + local origFrameRate + + -- Parse files + files = getFiles (currentDirectory+"/*.max") + + -- For each files + for i = 1 to files.count do + ( + -- File name + file = files[i] + + -- Progress bar + ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" + Progress.value = i*100/files.count + + if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then + ( + resetMAXFile #noprompt + + nllog("CONVERT " + file) + + -- Open the max project + if loadMaxFile file quiet:true == true then + ( + origAnimStart = animationRange.start + origAnimEnd = animationRange.end + origFrameRate = frameRate + + resetMAXFile #noprompt + + animationRange = interval origAnimStart origAnimEnd + frameRate = origFrameRate + + -- Merge the max project + if mergeMaxFile file quiet:true == true then + ( + result = call_do_it () + + -- Error ? + if result < 0 then + ( + if StopOnError.checked == true then + Messagebox ("Error in file " + file) + ) + else + ( + -- Save the max project ? + if (Test.checked == false) and (result != 0) then + ( + -- Backup the max project ? + local ok + ok = true + if BackupFiles.checked == true then + ( + -- Backup the file + if (BackupFile file) == false then + ( + -- Don't save the file because backup has failed + ok = false + + if StopOnError.checked == true then + Messagebox ("Can't backup file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + + -- Save the max project ? + if ok == true then + ( + if (saveMaxFile file) == true then + ( + fileModified = fileModified + 1 + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't write file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + ) + ) + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't load file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + ) + else + ( + nllog("SKIP " + file + " by tag") + ) + ) + + -- Parse sub directory ? + if (Recurse.checked == true) then + ( + local directories + + -- Get the directories + directories = getDirectories (currentDirectory+"/*") + + -- For each directories + for dir in directories do + ( + RecurseFolder dir + ) + ) + ) + + on BrowseDirectory pressed do + ( + local dir + try + ( + dir = getSavePath () -- caption:"Select the projects directory" + if dir != undefined then + Directory.text = dir + ) + catch + ( + ) + ) + + on GoButton pressed do + ( + -- Reset count + countModifications = 0 + countErrors = 0 + fileModified = 0 + fileParsed = 0 + + -- Get files in the shape_source_directory + if SourceFiles.state == 2 then + ( + -- Should warning user ? + if (SourceFiles.state == 2) and (Test.checked == false) then + ( + -- Warning ! + if ((queryBox "Warning, all the files in the specified folders will be overwrited.\nYou should backup your files before executing this script.\nDo you want to continue executing this script ?" beep:true) == true) then + RecurseFolder (adjustPathStringForScript Directory.text) + ) + else + ( + RecurseFolder (adjustPathStringForScript Directory.text) + ) + ) + else + ( + -- Just compute the current project + call_do_it () + ) + + -- Show errors + ProgressText.text = (fileParsed as string) + " project(s) opened, " + (countModifications as string) + " project modification(s), " + (fileModified as string) + " project(s) saved, " + (countErrors as string) + " error(s)." + Progress.value = 100 + ) +) + +assets_resave_floater = newRolloutFloater "NeL Assets Resave Database" 550 874 +addrollout assets_resave_rollout assets_resave_floater rolledUp:false + diff --git a/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave_hard.ms b/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave_hard.ms new file mode 100644 index 000000000..05220c7a5 --- /dev/null +++ b/code/nel/tools/3d/plugin_max/scripts/nel_assets_resave_hard.ms @@ -0,0 +1,316 @@ + +NEL3D_APPDATA_INTERFACE_FILE = 1423062700 + +-- Allocate 20 Me for the script +heapSize += 15000000 + +nlErrorFilename = "W:/database/conversion.log" +nlErrorStream = openFile nlErrorFilename mode:"w" +if nlErrorStream == undefined then + nlErrorStream = createFile nlErrorFilename + +-- Log a message +fn nllog message = +( + if nlErrorStream != undefined then + ( + format "%\n" message to:nlErrorStream + flush nlErrorStream + ) + + -- To the console + print message +) + +include "nel_utility.ms" + +rollout assets_resave_rollout "Properties" +( + fn do_it = + ( + max select none + + actionMan.executeAction 0 "40021" -- Selection: Select All + actionMan.executeAction 0 "311" -- Tools: Zoom Extents All Selected + actionMan.executeAction 0 "40807" -- Views: Activate All Maps + actionMan.executeAction 0 "63508" -- Views: Standard Display with Maps + actionMan.executeAction 0 "40043" -- Selection: Select None + + max views redraw + + return 1 + ) + + -- This script is a base script to include to add multiple functionality to your script + + -- To use this script + -- Include it in your script into the rollout at the beginning. + -- Implement a do_it function to do the job in your rollout. + -- The function should retun -1 if an arror occured, else the count of modification done + -- It the function returns <1, the project will not be overwritten + + Group "Running properties" + ( + RadioButtons SourceFiles "Source projects" labels:#("Current project", "All Projects in a folder") align:#left + + Label DirectoryLabel "Source directory" align:#left + EditText Directory "" width:500 align:#left enabled:false + Button BrowseDirectory "Browse..." align:#left enabled:false + + CheckBox Recurse "Look in subfolders" checked:true enabled:false + CheckBox Test "Test only, do not save" checked:false enabled:false + CheckBox BackupFiles "Backup files" checked:false enabled:false + CheckBox StopOnError "Stop on error" checked:false enabled:false + CheckBox UseTag "Use tag" checked:false enabled:false + + Label ProgressText width:500 align:#left + ProgressBar Progress width:500 align:#left + + Button GoButton "Go" width:500 align:#left + ) + + local countModifications + local countErrors + local fileModified + local fileParsed + + fn UpdateData = + ( + if SourceFiles.state == 2 then + isSourceDir = true + else + isSourceDir = false + if Test.checked == true then + isTest = true + else + isTest = false + + Directory.enabled = isSourceDir + BrowseDirectory.enabled = isSourceDir + Recurse.enabled = isSourceDir + Test.enabled = isSourceDir + BackupFiles.enabled = isSourceDir and (isTest == false) + StopOnError.enabled = isSourceDir + UseTag.enabled = isSourceDir + ) + + on SourceFiles changed state do + ( + UpdateData () + ) + + on Test changed state do + ( + UpdateData () + ) + + fn call_do_it = + ( + local result + + -- One more project + fileParsed = fileParsed + 1 + + -- Call it + result = do_it () + + -- Error ? + if result < 0 then + countErrors = countErrors + 1 + else + countModifications = countModifications + result + + -- Return result + return result + ) + + fn BackupFile file = + ( + local i + local newFilename + + i = 0 + while true do + ( + -- New file name + newFilename = file + ".backup_" + (i as string) + + -- File exist ? + if (fileExist newFilename) == false then + ( + if (copyFile file newFilename) == false then + return false + else + return true + ) + i = i + 1 + ) + ) + + fn RecurseFolder currentDirectory = + ( + resetMAXFile #noprompt + + local result + local file + local files + local origAnimStart + local origAnimEnd + local origFrameRate + + -- Parse files + files = getFiles (currentDirectory+"/*.max") + + -- For each files + for i = 1 to files.count do + ( + -- File name + file = files[i] + + -- Progress bar + ProgressText.text = "In directory "+currentDirectory+", compute file \"" + (getFilenameFile file) + "\"" + Progress.value = i*100/files.count + + if (UseTag.checked == false) or ((NeLTestFileDate file "W:/database/conversion.tag") == true) then + ( + resetMAXFile #noprompt + + nllog("CONVERT " + file) + + -- Merge the max project + if mergeMaxFile file quiet:true == true then + ( + result = call_do_it () + + -- Error ? + if result < 0 then + ( + if StopOnError.checked == true then + Messagebox ("Error in file " + file) + ) + else + ( + -- Save the max project ? + if (Test.checked == false) and (result != 0) then + ( + -- Backup the max project ? + local ok + ok = true + if BackupFiles.checked == true then + ( + -- Backup the file + if (BackupFile file) == false then + ( + -- Don't save the file because backup has failed + ok = false + + if StopOnError.checked == true then + Messagebox ("Can't backup file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + + -- Save the max project ? + if ok == true then + ( + if (saveMaxFile file) == true then + ( + fileModified = fileModified + 1 + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't write file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + ) + ) + ) + else + ( + if StopOnError.checked == true then + Messagebox ("Can't load file " + file) + + -- One more error + countErrors = countErrors + 1 + ) + ) + else + ( + nllog("SKIP " + file + " by tag") + ) + ) + + -- Parse sub directory ? + if (Recurse.checked == true) then + ( + local directories + + -- Get the directories + directories = getDirectories (currentDirectory+"/*") + + -- For each directories + for dir in directories do + ( + RecurseFolder dir + ) + ) + ) + + on BrowseDirectory pressed do + ( + local dir + try + ( + dir = getSavePath () -- caption:"Select the projects directory" + if dir != undefined then + Directory.text = dir + ) + catch + ( + ) + ) + + on GoButton pressed do + ( + -- Reset count + countModifications = 0 + countErrors = 0 + fileModified = 0 + fileParsed = 0 + + -- Get files in the shape_source_directory + if SourceFiles.state == 2 then + ( + -- Should warning user ? + if (SourceFiles.state == 2) and (Test.checked == false) then + ( + -- Warning ! + if ((queryBox "Warning, all the files in the specified folders will be overwrited.\nYou should backup your files before executing this script.\nDo you want to continue executing this script ?" beep:true) == true) then + RecurseFolder (adjustPathStringForScript Directory.text) + ) + else + ( + RecurseFolder (adjustPathStringForScript Directory.text) + ) + ) + else + ( + -- Just compute the current project + call_do_it () + ) + + -- Show errors + ProgressText.text = (fileParsed as string) + " project(s) opened, " + (countModifications as string) + " project modification(s), " + (fileModified as string) + " project(s) saved, " + (countErrors as string) + " error(s)." + Progress.value = 100 + ) +) + +assets_resave_floater = newRolloutFloater "NeL Assets Resave Database Hard" 550 874 +addrollout assets_resave_rollout assets_resave_floater rolledUp:false + diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 4e712a10d..f88849197 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -27,6 +27,7 @@ #include "nel/misc/system_utils.h" // 3D Interface. #include "nel/3d/bloom_effect.h" +#include "nel/3d/fxaa.h" #include "nel/3d/fasthls_modifier.h" #include "nel/3d/particle_system_manager.h" #include "nel/3d/particle_system.h" @@ -661,7 +662,7 @@ void release() delete &CLuaManager::getInstance(); NLGUI::CDBManager::release(); CWidgetManager::release(); - + diff --git a/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp b/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp index 5cb7c6922..a15f8c6d3 100644 --- a/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp +++ b/code/ryzom/tools/server/ai_build_wmap/build_proximity_maps.cpp @@ -27,7 +27,7 @@ #include "nel/misc/file.h" // Game share -#include "server_share/bmp4image.h" +#include "game_share/bmp4image.h" // AI share #include "ai_share/world_map.h" diff --git a/code/studio/src/plugins/gui_editor/CMakeLists.txt b/code/studio/src/plugins/gui_editor/CMakeLists.txt index 4b50ec8d1..2b46e2cdc 100644 --- a/code/studio/src/plugins/gui_editor/CMakeLists.txt +++ b/code/studio/src/plugins/gui_editor/CMakeLists.txt @@ -34,6 +34,8 @@ SET(OVQT_PLUGIN_GUI_EDITOR_HDR texture_chooser.h action_property_manager.h texture_property_manager.h + expression_editor.h + expr_link_dlg.h ) SET(OVQT_PLUGIN_GUI_EDITOR_UIS @@ -51,6 +53,8 @@ SET(OVQT_PLUGIN_GUI_EDITOR_UIS add_widget_widget.ui action_list.ui texture_chooser.ui + expression_editor.ui + expr_link_dlg.ui ) SET(QT_USE_QTGUI TRUE) diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp new file mode 100644 index 000000000..e8d01af85 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.cpp @@ -0,0 +1,124 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "expr_link_dlg.h" +#include + +ExprLinkDlg::ExprLinkDlg( QWidget *parent ) : +QDialog( parent ) +{ + m_ui.setupUi( this ); + + connect( m_ui.okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKClicked() ) ); + connect( m_ui.cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( onCancelClicked() ) ); +} + +ExprLinkDlg::~ExprLinkDlg() +{ +} + +void ExprLinkDlg::load( const QList< SlotInfo > &a, const QList< SlotInfo > &b, const QString &aname, const QString &bname ) +{ + QListIterator< SlotInfo > itra( a ); + QListIterator< SlotInfo > itrb( b ); + + while( itra.hasNext() ) + { + const SlotInfo &info = itra.next(); + + QListWidgetItem *item = new QListWidgetItem(); + item->setText( info.name ); + item->setData( Qt::UserRole, info.slot ); + + m_ui.list1->addItem( item ); + } + + while( itrb.hasNext() ) + { + const SlotInfo &info = itrb.next(); + + QListWidgetItem *item = new QListWidgetItem(); + item->setText( info.name ); + item->setData( Qt::UserRole, info.slot ); + + m_ui.list2->addItem( item ); + } + + m_ui.groupBox1->setTitle( aname ); + m_ui.groupBox2->setTitle( bname ); +} + +int ExprLinkDlg::getSlotA() const +{ + QListWidgetItem *item = m_ui.list1->currentItem(); + if( item == NULL ) + return -1; + + int slot = item->data( Qt::UserRole ).toInt(); + return slot; +} + +int ExprLinkDlg::getSlotB() const +{ + QListWidgetItem *item = m_ui.list2->currentItem(); + if( item == NULL ) + return -1; + + int slot = item->data( Qt::UserRole ).toInt(); + return slot; +} + +void ExprLinkDlg::onOKClicked() +{ + int slotA = getSlotA(); + int slotB = getSlotB(); + + if( ( slotA == -1 ) || ( slotB == -1 ) ) + { + QMessageBox::information( this, + tr( "No slots selected" ), + tr( "You need to select a slot on both sides." ) ); + return; + } + + if( ( slotA == 0 ) && ( slotB == 0 ) ) + { + QMessageBox::information( this, + tr( "Wrong slots selected" ), + tr( "You can only select the 'Out' slot on one of the sides." ) ); + return; + } + + if( ( slotA != 0 ) && ( slotB != 0 ) ) + { + QMessageBox::information( this, + tr( "Wrong slots selected" ), + tr( "One of the slots selected must be the 'Out' slot!" ) ); + return; + } + + accept(); +} + +void ExprLinkDlg::onCancelClicked() +{ + reject(); +} + + diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.h b/code/studio/src/plugins/gui_editor/expr_link_dlg.h new file mode 100644 index 000000000..3f3ba97c0 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.h @@ -0,0 +1,49 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef EXPR_LINK_DLG +#define EXPR_LINK_DLG + +#include +#include +#include "ui_expr_link_dlg.h" +#include "expr_slot_info.h" + +class ExprLinkDlg : public QDialog +{ + Q_OBJECT +public: + ExprLinkDlg( QWidget *parent = NULL ); + ~ExprLinkDlg(); + + void load( const QList< SlotInfo > &a, const QList< SlotInfo > &b, const QString &aname, const QString &bname ); + + int getSlotA() const; + int getSlotB() const; + +private Q_SLOTS: + void onOKClicked(); + void onCancelClicked(); + +private: + Ui::ExprLinkDialog m_ui; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expr_link_dlg.ui b/code/studio/src/plugins/gui_editor/expr_link_dlg.ui new file mode 100644 index 000000000..d6fdf9d7d --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expr_link_dlg.ui @@ -0,0 +1,76 @@ + + + ExprLinkDialog + + + + 0 + 0 + 641 + 334 + + + + Linking nodes + + + + + + + + GroupBox + + + + + + + + + + + + GroupBox + + + + + + + + + + + + + + Qt::Horizontal + + + + 398 + 20 + + + + + + + + Ok + + + + + + + Cancel + + + + + + + + diff --git a/code/studio/src/plugins/gui_editor/expr_slot_info.h b/code/studio/src/plugins/gui_editor/expr_slot_info.h new file mode 100644 index 000000000..470edf68d --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expr_slot_info.h @@ -0,0 +1,32 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef EXPR_SLOT_INFO +#define EXPR_SLOT_INFO + +#include + +struct SlotInfo +{ + QString name; + int slot; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.cpp b/code/studio/src/plugins/gui_editor/expression_editor.cpp new file mode 100644 index 000000000..392bdca41 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_editor.cpp @@ -0,0 +1,377 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "expression_editor.h" +#include +#include +#include +#include + +#include "expression_node.h" +#include "expression_link.h" +#include "expr_link_dlg.h" +#include "expression_store.h" +#include "expression_info.h" + +#include +#include + +class ExpressionEditorPvt +{ +public: + + ExpressionEditorPvt() + { + m_root = NULL; + } + + ExpressionStore store; + ExpressionNode *m_root; +}; + +ExpressionEditor::ExpressionEditor( QWidget *parent ) : +QMainWindow( parent ) +{ + m_ui.setupUi( this ); + + m_pvt = new ExpressionEditorPvt(); + + m_selectionCount = 0; + + m_scene = new QGraphicsScene( this ); + m_ui.view->setScene( m_scene ); + + connect( m_scene, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) ); + connect( m_ui.tree, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDblClicked( QTreeWidgetItem* ) ) ); + + m_nodeCount = 0; +} + +ExpressionEditor::~ExpressionEditor() +{ + delete m_pvt; + m_pvt = NULL; + m_scene = NULL; +} + +void ExpressionEditor::load() +{ + m_pvt->store.load(); + + QList< const ExpressionInfo* > l; + m_pvt->store.getExpressions( l ); + + QListIterator< const ExpressionInfo* > itr( l ); + while( itr.hasNext() ) + { + addExpression( itr.next() ); + } + + l.clear(); +} + +void ExpressionEditor::contextMenuEvent( QContextMenuEvent *e ) +{ + QMenu menu; + QAction *a = NULL; + + if( m_selectionCount > 0 ) + { + a = menu.addAction( "Remove" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onDeleteSelection() ) ); + + if( m_selectionCount == 1 ) + { + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *node = dynamic_cast< ExpressionNode* >( l[ 0 ] ); + if( node != NULL ) + { + if( node->variable() ) + { + a = menu.addAction( "Change slot count" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onChangeSlotCount() ) ); + } + else + if( node->isValue() ) + { + a = menu.addAction( "Change value" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onChangeValue() ) ); + } + + a = menu.addAction( "Set as root" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onSetRoot() ) ); + } + } + else + if( m_selectionCount == 2 ) + { + a = menu.addAction( "Link" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onLinkItems() ) ); + } + + a = menu.addAction( "Unlink" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onUnLinkItems() ) ); + } + else + { + a = menu.addAction( "Build expression" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onBuildExpression() ) ); + + a = menu.addAction( "Save" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onSave() ) ); + + a = menu.addAction( "Clear" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onClear() ) ); + } + + menu.exec( e->globalPos() ); +} + +void ExpressionEditor::closeEvent( QCloseEvent *e ) +{ + QMainWindow::closeEvent( e ); + + Q_EMIT closing(); +} + +void ExpressionEditor::onDeleteSelection() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + QListIterator< QGraphicsItem* > itr( l ); + while( itr.hasNext() ) + { + QGraphicsItem *item = itr.next(); + + ExpressionNode *node = dynamic_cast< ExpressionNode* >( item ); + if( node != NULL ) + { + ExpressionLink *link = NULL; + + int c = node->slotCount(); + for( int i = 0; i < c; i++ ) + { + link = node->link( i ); + if( link != NULL ) + { + link->unlink(); + m_scene->removeItem( link ); + delete link; + } + } + } + + m_scene->removeItem( item ); + delete item; + } +} + +void ExpressionEditor::onSelectionChanged() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + m_selectionCount = l.count(); +} + +void ExpressionEditor::onLinkItems() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *from = static_cast< ExpressionNode* >( l[ 0 ] ); + ExpressionNode *to = static_cast< ExpressionNode* >( l[ 1 ] ); + + QList< SlotInfo > froml; + QList< SlotInfo > tol; + + from->getSlots( froml ); + to->getSlots( tol ); + + // If there are no free slots, or both "Out" slots are taken we can't link + if( froml.isEmpty() || tol.isEmpty() || ( !from->slotEmpty( 0 ) && !to->slotEmpty( 0 ) ) ) + { + QMessageBox::information( this, + tr( "Failed to link nodes" ), + tr( "Unfortunately those nodes are full." ) ); + return; + } + + ExprLinkDlg d; + d.load( froml, tol, from->name(), to->name() ); + int result = d.exec(); + if( result == QDialog::Rejected ) + return; + + int slotA = d.getSlotA(); + int slotB = d.getSlotB(); + + ExpressionLink *link = new ExpressionLink(); + link->link( from, to, slotA, slotB ); + + m_scene->addItem( link ); +} + +void ExpressionEditor::onUnLinkItems() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + + for( int i = 0; i < l.count(); i++ ) + { + ExpressionNode *node = dynamic_cast< ExpressionNode* >( l[ i ] ); + if( node == NULL ) + continue; + + node->clearLinks(); + } +} + +void ExpressionEditor::onItemDblClicked( QTreeWidgetItem *item ) +{ + QString name = item->text( 0 ); + + const ExpressionInfo *info = m_pvt->store.getInfo( name ); + + QString n = name; + n += " #"; + n += QString::number( m_nodeCount ); + m_nodeCount++; + + ExpressionNode *node = new ExpressionNode( n, info->slotNames.count() ); + node->setSlotNames( info->slotNames ); + node->setVariable( info->variable ); + node->setIsValue( info->value ); + if( node->isValue() ) + { + node->setValue( "Value" ); + } + m_scene->addItem( node ); +} + +void ExpressionEditor::onChangeSlotCount() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] ); + int oldc = node->slotCount(); + + int c = QInputDialog::getInt( this, + tr( "Change slot count" ), + tr( "Enter new slot count" ), + oldc, + 1, + 26 ); + + if( oldc == c ) + return; + + node->changeSlotCount( c ); +} + +void ExpressionEditor::onChangeValue() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] ); + + QString oldValue = node->getValue(); + + QString newValue = QInputDialog::getText( this, + tr( "Change value" ), + tr( "Enter new value" ), + QLineEdit::Normal, + oldValue ); + + if( newValue.isEmpty() ) + return; + if( newValue == oldValue ) + return; + + node->setValue( newValue ); +} + +void ExpressionEditor::onSetRoot() +{ + QList< QGraphicsItem* > l = m_scene->selectedItems(); + ExpressionNode *node = static_cast< ExpressionNode* >( l[ 0 ] ); + + if( m_pvt->m_root != NULL ) + m_pvt->m_root->setRoot( false ); + + m_pvt->m_root = node; + node->setRoot( true ); +} + +void ExpressionEditor::onBuildExpression() +{ + if( m_pvt->m_root == NULL ) + { + QMessageBox::information( this, + tr( "Building expression" ), + tr( "Failed to build expression: You must set a root node." ) ); + return; + } + + QString result = m_pvt->m_root->build(); + QMessageBox::information( this, + tr( "Building expression" ), + tr( "The result is\n" ) + result ); +} + +void ExpressionEditor::onSave() +{ + if( m_pvt->m_root != NULL ) + { + m_result = m_pvt->m_root->build(); + } + + close(); +} + +void ExpressionEditor::onClear() +{ + m_scene->clear(); + m_pvt->m_root = NULL; + m_nodeCount = 0; + m_selectionCount = 0; + m_result = ""; +} + + +void ExpressionEditor::addExpression( const ExpressionInfo *info ) +{ + QTreeWidgetItem *item = findTopLevelItem( info->category ); + if( item == NULL ) + { + item = new QTreeWidgetItem(); + item->setText( 0, info->category ); + m_ui.tree->addTopLevelItem( item ); + } + + QTreeWidgetItem *citem = new QTreeWidgetItem(); + citem->setText( 0, info->name ); + item->addChild( citem ); +} + +QTreeWidgetItem* ExpressionEditor::findTopLevelItem( const QString &text ) +{ + int c = m_ui.tree->topLevelItemCount(); + for( int i = 0; i < c; i++ ) + { + QTreeWidgetItem *item = m_ui.tree->topLevelItem( i ); + if( item->text( 0 ) == text ) + return item; + } + + return NULL; +} + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.h b/code/studio/src/plugins/gui_editor/expression_editor.h new file mode 100644 index 000000000..92cc959bd --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_editor.h @@ -0,0 +1,75 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef EXPRESSION_EDITOR +#define EXPRESSION_EDITOR + +#include "ui_expression_editor.h" + +class QGraphicsScene; +class QGraphicsItem; +class ExpressionEditorPvt; +class ExpressionInfo; + +class ExpressionEditor : public QMainWindow +{ + Q_OBJECT +public: + ExpressionEditor( QWidget *parent = NULL ); + ~ExpressionEditor(); + + void load(); + QString result() const{ return m_result; } + +Q_SIGNALS: + void closing(); + +protected: + void contextMenuEvent( QContextMenuEvent *e ); + void closeEvent( QCloseEvent *e ); + +private Q_SLOTS: + void onDeleteSelection(); + void onSelectionChanged(); + void onLinkItems(); + void onUnLinkItems(); + void onItemDblClicked( QTreeWidgetItem *item ); + void onChangeSlotCount(); + void onChangeValue(); + void onSetRoot(); + void onBuildExpression(); + void onSave(); + void onClear(); + +private: + void addExpression( const ExpressionInfo *info ); + QTreeWidgetItem* findTopLevelItem( const QString &text ); + + Ui::ExpressionEditor m_ui; + QGraphicsScene *m_scene; + + int m_selectionCount; + int m_nodeCount; + + ExpressionEditorPvt *m_pvt; + QString m_result; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_editor.ui b/code/studio/src/plugins/gui_editor/expression_editor.ui new file mode 100644 index 000000000..fa21420a2 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_editor.ui @@ -0,0 +1,58 @@ + + + ExpressionEditor + + + Qt::ApplicationModal + + + + 0 + 0 + 800 + 600 + + + + Expression Editor + + + + + + + + + + + + 0 + 0 + 800 + 21 + + + + + + + 1 + + + + + + + + Expressions + + + + + + + + + + + diff --git a/code/studio/src/plugins/gui_editor/expression_info.h b/code/studio/src/plugins/gui_editor/expression_info.h new file mode 100644 index 000000000..86218b6af --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_info.h @@ -0,0 +1,41 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPRESSION_INFO +#define EXPRESSION_INFO + +#include +#include + +struct ExpressionInfo +{ + QString name; + bool value; + QString category; + bool variable; + QStringList slotNames; + + ExpressionInfo() + { + value = false; + variable = false; + } +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_link.cpp b/code/studio/src/plugins/gui_editor/expression_link.cpp new file mode 100644 index 000000000..54c7734b0 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_link.cpp @@ -0,0 +1,78 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "expression_link.h" +#include "expression_node.h" +#include +#include + +ExpressionLink::ExpressionLink( QGraphicsItem *parent ) : +QGraphicsLineItem( parent ) +{ + m_from = NULL; + m_to = NULL; +} + +ExpressionLink::~ExpressionLink() +{ + unlink(); +} + +void ExpressionLink::link( ExpressionNode *from, ExpressionNode *to, int fromSlot, int toSlot ) +{ + m_from = from; + m_to = to; + m_from->setLink( this, fromSlot ); + m_to->setLink( this, toSlot ); + + m_fromSlot = fromSlot; + m_toSlot = toSlot; + + nodeMoved(); +} + +void ExpressionLink::unlink() +{ + if( m_from == NULL ) + return; + + m_from->setLink( NULL, m_fromSlot ); + m_to->setLink( NULL, m_toSlot ); + + m_from = NULL; + m_to = NULL; + + delete this; +} + +void ExpressionLink::nodeMoved() +{ + setLine( QLineF( m_from->slotPos( m_fromSlot ), m_to->slotPos( m_toSlot ) ) ); +} + +void ExpressionLink::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) +{ + QPen p; + p.setColor( Qt::black ); + p.setWidth( 5 ); + setPen( p ); + + QGraphicsLineItem::paint( painter, option, widget ); +} + + diff --git a/code/studio/src/plugins/gui_editor/expression_link.h b/code/studio/src/plugins/gui_editor/expression_link.h new file mode 100644 index 000000000..a0e699451 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_link.h @@ -0,0 +1,51 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPRESSION_LINK +#define EXPRESSION_LINK + +#include + +class ExpressionNode; + +class ExpressionLink : public QGraphicsLineItem +{ +public: + ExpressionLink( QGraphicsItem *parent = NULL ); + ~ExpressionLink(); + + void link( ExpressionNode *from, ExpressionNode *to, int fromSlot, int toSlot ); + void unlink(); + + void nodeMoved(); + + void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); + + ExpressionNode* from() const{ return m_from; } + ExpressionNode* to() const{ return m_to; } + +private: + ExpressionNode *m_from; + ExpressionNode *m_to; + + int m_fromSlot; + int m_toSlot; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_loader.cpp b/code/studio/src/plugins/gui_editor/expression_loader.cpp new file mode 100644 index 000000000..07db432e0 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_loader.cpp @@ -0,0 +1,220 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "expression_loader.h" +#include "expression_info.h" + +#include +#include + +class ExpressionLoaderPvt +{ +public: + + bool parseName() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + m_info->name = text; + + return true; + } + + bool parseValue() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + if( text.toLower() == "true" ) + m_info->value = true; + else + m_info->value = false; + + return true; + } + + bool parseCategory() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + m_info->category = text; + + return true; + } + + bool parseVariable() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + if( text.toLower() == "true" ) + m_info->variable = true; + else + m_info->variable = false; + + return true; + } + + bool parseSlot() + { + QString text = reader.readElementText( QXmlStreamReader::ErrorOnUnexpectedElement ); + if( reader.hasError() ) + return false; + + m_info->slotNames.push_back( text ); + + return true; + } + + bool parseSlots() + { + bool error = false; + + while( !reader.atEnd() ) + { + reader.readNext(); + + if( reader.isStartElement() ) + { + QString name = reader.name().toString(); + if( name == "slot" ) + error = !parseSlot(); + } + else + if( reader.isEndElement() ) + { + if( reader.name() == "slots" ) + break; + } + } + + if( reader.atEnd() ) + return false; + + return true; + } + + bool load( QFile *f ) + { + reader.clear(); + reader.setDevice( f ); + + bool error = false; + + // start of document + reader.readNext(); + if( reader.atEnd() ) + return false; + + // root node + reader.readNext(); + if( reader.atEnd() ) + return false; + + if( reader.isStartElement() ) + { + // Not an expression file? + if( reader.name() != "expression" ) + return false; + } + + while( !reader.atEnd() ) + { + reader.readNext(); + + if( reader.isStartElement() ) + { + QString name = reader.name().toString(); + + if( name == "name" ) + error = !parseName(); + else + if( name == "value" ) + error = !parseValue(); + else + if( name == "category" ) + error = !parseCategory(); + else + if( name == "variable" ) + error = !parseVariable(); + else + if( name == "slots" ) + error = !parseSlots(); + } + + if( error ) + break; + } + + if( error || reader.hasError() ) + { + return false; + } + + return true; + } + + void setInfo( ExpressionInfo *info ){ m_info = info; } + +private: + QXmlStreamReader reader; + ExpressionInfo *m_info; +}; + +ExpressionLoader::ExpressionLoader() +{ + m_pvt = new ExpressionLoaderPvt; +} + +ExpressionLoader::~ExpressionLoader() +{ + delete m_pvt; + m_pvt = NULL; +} + +ExpressionInfo* ExpressionLoader::load( const QString &filename ) +{ + ExpressionInfo *info = NULL; + bool ok = false; + + QFile f( filename ); + if( !f.open( QIODevice::ReadOnly | QIODevice::Text ) ) + return NULL; + + info = new ExpressionInfo(); + m_pvt->setInfo( info ); + ok = m_pvt->load( &f ); + + f.close(); + + if( !ok ) + { + delete info; + info = NULL; + } + + return info; +} + + diff --git a/code/studio/src/plugins/gui_editor/expression_loader.h b/code/studio/src/plugins/gui_editor/expression_loader.h new file mode 100644 index 000000000..f315fcdcd --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_loader.h @@ -0,0 +1,39 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPRESSION_LOADER +#define EXPRESSION_LOADER + +struct ExpressionInfo; +class QString; +class ExpressionLoaderPvt; + +class ExpressionLoader +{ +public: + ExpressionLoader(); + ~ExpressionLoader(); + + ExpressionInfo* load( const QString &filename ); + +private: + ExpressionLoaderPvt *m_pvt; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_node.cpp b/code/studio/src/plugins/gui_editor/expression_node.cpp new file mode 100644 index 000000000..8a0ef774b --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_node.cpp @@ -0,0 +1,410 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "expression_node.h" +#include "expression_link.h" +#include +#include + +struct NodeSlotInfo +{ + // top-left + QPoint tl; + + // text top-left + QPoint ttl; + + // The text displayed + QString text; + + // text width + qreal tw; + + // text height + qreal th; + + // width-height of the box + qreal wh; +}; + +class NodeSlot +{ +public: + NodeSlot( const NodeSlotInfo &info ) + { + m_info = info; + } + + ~NodeSlot() + { + } + + QPointF pos() const{ + QPointF p; + p.setX( m_info.tl.x() + m_info.wh / 2.0 ); + p.setY( m_info.tl.y() + m_info.wh / 2.0 ); + + return p; + } + + void paint( QPainter *painter ) + { + QBrush boxBrush; + QPen p; + + boxBrush.setColor( Qt::black ); + boxBrush.setStyle( Qt::SolidPattern ); + p.setColor( Qt::black ); + painter->setPen( p ); + + QRectF box; + QRectF tbox; + + box.setTopLeft( m_info.tl ); + box.setHeight( m_info.wh ); + box.setWidth( m_info.wh ); + + painter->fillRect( box, boxBrush ); + + tbox.setTopLeft( m_info.ttl ); + tbox.setHeight( m_info.th ); + tbox.setWidth( m_info.tw ); + + painter->drawText( tbox, Qt::AlignRight, m_info.text ); + } + + QString text() const{ return m_info.text; } + void setText( const QString &text ){ m_info.text = text; } + +private: + NodeSlotInfo m_info; +}; + + + +ExpressionNode::ExpressionNode( const QString &name, int slotCount, QGraphicsItem *parent ) : +QGraphicsItem( parent ) +{ + setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsScenePositionChanges ); + + m_w = 100; + m_h = 100; + m_hh = 20.0; + + m_variable = false; + m_isValue = false; + m_isRoot = false; + + m_name = name; + + if( slotCount > 3 ) + m_h = m_h + 20.0 * ( slotCount - 3 ); + + createSlots( slotCount ); +} + +ExpressionNode::~ExpressionNode() +{ + clearLinks(); + clearSlots(); +} + +QRectF ExpressionNode::boundingRect() const +{ + return QRectF( 0, 0, m_w, m_h ); +} + +void ExpressionNode::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ) +{ + QBrush br; + QBrush boxBrush; + QPen p; + QColor c; + + QRectF rect = boundingRect(); + QRectF header = rect; + header.setHeight( m_hh ); + + // Draw filled rectangle, header + if( !m_isRoot ) + { + c.setRed( 44 ); + c.setGreen( 169 ); + c.setBlue( 232 ); + } + else + { + c.setRed( 255 ); + c.setGreen( 0 ); + c.setBlue( 0 ); + } + br.setColor( c ); + br.setStyle( Qt::SolidPattern ); + p.setColor( c ); + painter->setPen( p ); + painter->fillRect( header, br ); + + // Draw header text + p.setColor( Qt::black ); + painter->setPen( p ); + painter->drawText( header, Qt::AlignCenter, m_name ); + + // Draw value if applicable + if( m_isValue ) + { + QRectF vbox; + vbox.setTopLeft( QPoint( 0.0, 20.0 ) ); + vbox.setWidth( header.width() ); + vbox.setHeight( header.height() ); + QPen vpen; + vpen.setColor( Qt::red ); + painter->setPen( vpen ); + painter->drawText( vbox, Qt::AlignCenter, m_value ); + painter->setPen( p ); + } + + if( option->state & QStyle::State_Selected ) + { + p.setStyle( Qt::DotLine ); + p.setColor( Qt::red ); + } + + // Draw outline of the entire thing + header + painter->setPen( p ); + painter->drawRect( rect ); + painter->drawRect( header ); + + paintSlots( painter ); +} + + +QPointF ExpressionNode::slotPos( int slot ) const +{ + const NodeSlot *s = m_slots[ slot ]; + QPointF sp = s->pos(); + QPointF mp = pos(); + + mp += sp; + return mp; +} + +void ExpressionNode::changeSlotCount( int count ) +{ + clearSlots(); + clearLinks(); + m_links.clear(); + + if( count <= 3 ) + m_h = 100.0; + else + m_h = 100.0 + 20.0 * ( count - 3 ); + + createSlots( count ); + + update(); +} + +void ExpressionNode::clearSlots() +{ + qDeleteAll( m_slots ); + m_slots.clear(); +} + +bool ExpressionNode::slotEmpty( int slot ) const +{ + if( m_links[ 0 ] == NULL ) + return true; + else + return false; +} + +void ExpressionNode::getSlots( QList< SlotInfo > &l ) +{ + SlotInfo info; + + for( int i = 0; i < m_slots.count(); i++ ) + { + if( m_links[ i ] != NULL ) + continue; + + info.name = m_slots[ i ]->text(); + info.slot = i; + l.push_back( info ); + } +} + +void ExpressionNode::setLink( ExpressionLink *link, int slot ) +{ + m_links[ slot ] = link; +} + +ExpressionLink* ExpressionNode::link( int slot ) const +{ + return m_links[ slot ]; +} + +void ExpressionNode::setSlotNames( const QList< QString > &l ) +{ + int c = l.count(); + for( int i = 0; i < c; i++ ) + { + // "Out" slot is at position 0, so set the names with an offset of 1 + m_slots[ i + 1 ]->setText( l[ i ] ); + } +} + +void ExpressionNode::setValue( const QString &value ) +{ + m_value = value; + + int c = m_value.count(); + if( c < 15 ) + m_w = 100.0; + else + m_w = m_w + ( 100.0 / 15.0 ) * ( c - 15.0 ); + + update(); +} + +void ExpressionNode::setRoot( bool b ) +{ + m_isRoot = b; + update(); +} + +QString ExpressionNode::build() const +{ + QString result; + + if( isValue() ) + return m_value; + + QStringList l = m_name.split( ' ' ); + result = l[ 0 ]; + result += "( "; + + int c = m_links.count(); + for( int i = 1; i < c; i++ ) + { + ExpressionLink *link = m_links[ i ]; + if( link == NULL ) + continue; + + ExpressionNode *node = NULL; + + if( link->from() == this ) + node = link->to(); + else + node = link->from(); + + result += node->build(); + + if( i != ( c - 1 ) ) + result += ", "; + } + + result += " )"; + return result; +} + +QVariant ExpressionNode::itemChange( GraphicsItemChange change, const QVariant &value ) +{ + if( change == ItemScenePositionHasChanged ) + { + onNodeMove(); + } + + return QGraphicsItem::itemChange( change, value ); +} + +void ExpressionNode::onNodeMove() +{ + for( int i = 0; i < m_links.count(); i++ ) + { + ExpressionLink *link = m_links[ i ]; + if( link == NULL ) + continue; + + link->nodeMoved(); + } +} + +void ExpressionNode::createSlots( int count) +{ + // Out nodes + m_links.push_back( NULL ); + + for( int i = 0; i < count; i++ ) + m_links.push_back( NULL ); + + // First create the "Out" slot + NodeSlotInfo info; + info.tw = 25.0; + info.th = 12.0; + info.wh = 10.0; + + qreal x = 0.0; + qreal y = m_h * 0.5; + qreal tx = info.wh; + qreal ty = m_h * 0.5 - 2; + + info.tl = QPoint( x, y ); + info.ttl = QPoint( tx, ty ); + info.text = "Out"; + + m_slots.push_back( new NodeSlot( info ) ); + + // Then the rest of them + for( int i = 0; i < count; i++ ) + { + x = m_w - info.wh; + y = 30 + i * 20.0; + tx = x - 5 - info.tw; + ty = y - 2; + + info.tl = QPoint( x, y ); + info.ttl = QPoint( tx, ty ); + info.text = QString( 'A' + i ); + + m_slots.push_back( new NodeSlot( info ) ); + } +} + +void ExpressionNode::paintSlots( QPainter *painter ) +{ + for( int i = 0; i < m_slots.count(); i++ ) + { + NodeSlot *slot = m_slots[ i ]; + slot->paint( painter ); + } +} + + +void ExpressionNode::clearLinks() +{ + for( int i = 0; i < m_links.count(); i++ ) + { + ExpressionLink *link = m_links[ i ]; + if( link == NULL ) + continue; + + link->unlink(); + } +} + diff --git a/code/studio/src/plugins/gui_editor/expression_node.h b/code/studio/src/plugins/gui_editor/expression_node.h new file mode 100644 index 000000000..1e0290344 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_node.h @@ -0,0 +1,95 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef EXPRESSION_NODE +#define EXPRESSION_NODE + +#include +#include +#include "expr_slot_info.h" + +class ExpressionLink; +class NodeSlot; + +class ExpressionNode : public QGraphicsItem +{ +public: + ExpressionNode( const QString &name, int slotCount = 3, QGraphicsItem *parent = NULL ); + ~ExpressionNode(); + + QRectF boundingRect() const; + void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget ); + + void setLink( ExpressionLink *link, int slot ); + ExpressionLink* link( int slot ) const; + + QPointF slotPos( int slot ) const; + + int slotCount() const{ return m_slots.count(); } + void changeSlotCount( int count ); + void clearSlots(); + + bool slotEmpty( int slot ) const; + + void getSlots( QList< SlotInfo > &l ); + + void clearLinks(); + + QString name() const{ return m_name; } + + void setSlotNames( const QList< QString > &l ); + + void setVariable( bool b ){ m_variable = b; } + bool variable() const{ return m_variable; } + + void setValue( const QString &value ); + QString getValue() const{ return m_value; } + + bool isValue() const{ return m_isValue; } + void setIsValue( bool b ){ m_isValue = b; } + void setRoot( bool b ); + + QString build() const; + +protected: + QVariant itemChange( GraphicsItemChange change, const QVariant &value ); + +private: + void onNodeMove(); + void createSlots( int count = 3 ); + void paintSlots( QPainter *painter ); + + qreal m_w; // node width + qreal m_h; // node height + qreal m_hh; // header height + + QList< NodeSlot* > m_slots; + QList< ExpressionLink* > m_links; + + QString m_name; + + bool m_variable; + + QString m_value; + bool m_isValue; + bool m_isRoot; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expression_store.cpp b/code/studio/src/plugins/gui_editor/expression_store.cpp new file mode 100644 index 000000000..9f2218b4e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_store.cpp @@ -0,0 +1,105 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "expression_store.h" +#include "expression_info.h" +#include "expression_loader.h" +#include +#include + +class ExpressionStorePvt +{ +public: + + ~ExpressionStorePvt() + { + qDeleteAll( expressions ); + expressions.clear(); + } + + + QMap< QString, ExpressionInfo* > expressions; +}; + +ExpressionStore::ExpressionStore() +{ + m_pvt = new ExpressionStorePvt(); +} + +ExpressionStore::~ExpressionStore() +{ + delete m_pvt; + m_pvt = NULL; +} + + +bool ExpressionStore::load() +{ + QDir d( "expressions" ); + if( !d.exists() ) + return false; + + QFileInfoList l = d.entryInfoList(); + QListIterator< QFileInfo > itr( l ); + if( !itr.hasNext() ) + return false; + + ExpressionLoader loader; + + while( itr.hasNext() ) + { + const QFileInfo &info = itr.next(); + if( !info.isFile() ) + continue; + + if( info.suffix() != "xml" ) + continue; + + ExpressionInfo *expr = loader.load( info.absoluteFilePath() ); + if( expr == NULL ) + continue; + + m_pvt->expressions[ expr->name ] = expr; + } + + return false; +} + +void ExpressionStore::getExpressions( QList< const ExpressionInfo* > &l ) const +{ + l.clear(); + + QMap< QString, ExpressionInfo* >::const_iterator itr = m_pvt->expressions.constBegin(); + while( itr != m_pvt->expressions.constEnd() ) + { + l.push_back( itr.value() ); + ++itr; + } +} + +const ExpressionInfo* ExpressionStore::getInfo( const QString &name ) +{ + QMap< QString, ExpressionInfo* >::const_iterator itr = m_pvt->expressions.find( name ); + if( itr == m_pvt->expressions.end() ) + return NULL; + else + return itr.value(); +} + + + diff --git a/code/studio/src/plugins/gui_editor/expression_store.h b/code/studio/src/plugins/gui_editor/expression_store.h new file mode 100644 index 000000000..9c29fa0f6 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expression_store.h @@ -0,0 +1,46 @@ +// Ryzom Core Studio - GUI Editor Plugin +// +// Copyright (C) 2014 Laszlo Kis-Adam +// Copyright (C) 2010 Ryzom Core +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef EXPRESSION_STORE +#define EXPRESSION_STORE + +#include +#include +#include "expression_info.h" + +//struct ExpressionInfo; +class ExpressionStorePvt; + +class ExpressionStore +{ +public: + ExpressionStore(); + ~ExpressionStore(); + + bool load(); + + void getExpressions( QList< const ExpressionInfo* > &l ) const; + + const ExpressionInfo* getInfo( const QString &name ); + +private: + ExpressionStorePvt *m_pvt; +}; + +#endif + diff --git a/code/studio/src/plugins/gui_editor/expressions/add.xml b/code/studio/src/plugins/gui_editor/expressions/add.xml new file mode 100644 index 000000000..62cec88af --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/add.xml @@ -0,0 +1,9 @@ + +Mathematical +add +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/and.xml b/code/studio/src/plugins/gui_editor/expressions/and.xml new file mode 100644 index 000000000..cc8c05c6e --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/and.xml @@ -0,0 +1,9 @@ + +Logical +and +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/div.xml b/code/studio/src/plugins/gui_editor/expressions/div.xml new file mode 100644 index 000000000..aba3faffc --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/div.xml @@ -0,0 +1,9 @@ + +Mathematical +div +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/eq.xml b/code/studio/src/plugins/gui_editor/expressions/eq.xml new file mode 100644 index 000000000..77b7041cc --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/eq.xml @@ -0,0 +1,9 @@ + +Logical +eq +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml b/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml new file mode 100644 index 000000000..248a68332 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/ifthenelse.xml @@ -0,0 +1,10 @@ + +Logical +ifthenelse +false + +if +then +else + + diff --git a/code/studio/src/plugins/gui_editor/expressions/mul.xml b/code/studio/src/plugins/gui_editor/expressions/mul.xml new file mode 100644 index 000000000..54d03b025 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/mul.xml @@ -0,0 +1,9 @@ + +Mathematical +mul +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/ne.xml b/code/studio/src/plugins/gui_editor/expressions/ne.xml new file mode 100644 index 000000000..31d62af02 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/ne.xml @@ -0,0 +1,9 @@ + +Logical +ne +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/not.xml b/code/studio/src/plugins/gui_editor/expressions/not.xml new file mode 100644 index 000000000..872b9b7a4 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/not.xml @@ -0,0 +1,8 @@ + +Logical +not +false + +A + + diff --git a/code/studio/src/plugins/gui_editor/expressions/or.xml b/code/studio/src/plugins/gui_editor/expressions/or.xml new file mode 100644 index 000000000..2d977267c --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/or.xml @@ -0,0 +1,9 @@ + +Logical +or +true + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/sub.xml b/code/studio/src/plugins/gui_editor/expressions/sub.xml new file mode 100644 index 000000000..5f35c2895 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/sub.xml @@ -0,0 +1,9 @@ + +Mathematical +sub +false + +A +B + + diff --git a/code/studio/src/plugins/gui_editor/expressions/value.xml b/code/studio/src/plugins/gui_editor/expressions/value.xml new file mode 100644 index 000000000..9bd57fc95 --- /dev/null +++ b/code/studio/src/plugins/gui_editor/expressions/value.xml @@ -0,0 +1,6 @@ + +Value +value +true +false + diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp index 3f4e318db..9f6568936 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.cpp +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.cpp @@ -44,7 +44,6 @@ #include "editor_selection_watcher.h" #include "editor_message_processor.h" #include "add_widget_widget.h" -#include "texture_chooser.h" namespace GUIEditor { @@ -71,8 +70,6 @@ namespace GUIEditor widgetInfoTree = new CWidgetInfoTree; - tc = new TextureChooser(); - createMenus(); readSettings(); @@ -118,9 +115,6 @@ namespace GUIEditor removeMenus(); - delete tc; - tc = NULL; - delete messageProcessor; messageProcessor = NULL; @@ -359,12 +353,6 @@ namespace GUIEditor GUICtrl->show(); } - void GUIEditorWindow::onTCClicked() - { - tc->load(); - tc->exec(); - } - void GUIEditorWindow::createMenus() { Core::MenuManager *mm = Core::ICore::instance()->menuManager(); @@ -411,10 +399,6 @@ namespace GUIEditor connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onAddWidgetClicked() ) ); m->addAction( a ); - a = new QAction( "Texture Chooser", this ); - connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onTCClicked() ) ); - m->addAction( a ); - menu = m; } } diff --git a/code/studio/src/plugins/gui_editor/gui_editor_window.h b/code/studio/src/plugins/gui_editor/gui_editor_window.h index d18a24813..cc2dfbc65 100644 --- a/code/studio/src/plugins/gui_editor/gui_editor_window.h +++ b/code/studio/src/plugins/gui_editor/gui_editor_window.h @@ -25,11 +25,8 @@ #include "property_browser_ctrl.h" class QtTreePropertyBrowser; - class QMenu; -class TextureChooser; - namespace GUIEditor { @@ -67,8 +64,6 @@ private Q_SLOTS: void onGUILoaded(); void onAddWidgetClicked(); void onTreeChanged(); - void onTCClicked(); - protected: void hideEvent( QHideEvent *evnt ); @@ -101,8 +96,6 @@ private: QString currentProjectFile; QMenu *menu; - - TextureChooser *tc; }; } diff --git a/code/studio/src/plugins/gui_editor/link_editor.cpp b/code/studio/src/plugins/gui_editor/link_editor.cpp index c57a6cd09..3cb49f37a 100644 --- a/code/studio/src/plugins/gui_editor/link_editor.cpp +++ b/code/studio/src/plugins/gui_editor/link_editor.cpp @@ -18,20 +18,49 @@ #include "link_editor.h" #include "nel/gui/interface_group.h" #include "nel/gui/widget_manager.h" +#include "expression_editor.h" +#include namespace GUIEditor { + class LinkEditorPvt + { + public: + + LinkEditorPvt() + { + ee = new ExpressionEditor(); + ee->load(); + } + + ~LinkEditorPvt() + { + delete ee; + ee = NULL; + } + + ExpressionEditor *ee; + }; + + LinkEditor::LinkEditor( QWidget *parent ) : QWidget( parent ) { setupUi( this ); setup(); + + m_pvt = new LinkEditorPvt(); + connect( okButton, SIGNAL( clicked( bool ) ), this, SLOT( onOKButtonClicked() ) ); connect( cancelButton, SIGNAL( clicked( bool ) ), this, SLOT( hide() ) ); + connect( expressionEdit, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( onTextEditContextMenu( const QPoint& ) ) ); + connect( m_pvt->ee, SIGNAL( closing() ), this, SLOT( onEEClosing() ) ); } LinkEditor::~LinkEditor() { + delete m_pvt; + m_pvt = NULL; } void LinkEditor::setup() @@ -89,4 +118,23 @@ namespace GUIEditor hide(); } + + void LinkEditor::onTextEditContextMenu( const QPoint &pos ) + { + QMenu *menu = expressionEdit->createStandardContextMenu(); + QAction *a = menu->addAction( "Expression Editor" ); + connect( a, SIGNAL( triggered() ), this, SLOT( onEE() ) ); + + menu->exec( mapToGlobal( pos ) ); + } + + void LinkEditor::onEE() + { + m_pvt->ee->show(); + } + + void LinkEditor::onEEClosing() + { + expressionEdit->setPlainText( m_pvt->ee->result() ); + } } diff --git a/code/studio/src/plugins/gui_editor/link_editor.h b/code/studio/src/plugins/gui_editor/link_editor.h index b70019d20..f5617982e 100644 --- a/code/studio/src/plugins/gui_editor/link_editor.h +++ b/code/studio/src/plugins/gui_editor/link_editor.h @@ -23,6 +23,8 @@ namespace GUIEditor { + class LinkEditorPvt; + class LinkEditor : public QWidget, public Ui::LinkEditor { Q_OBJECT @@ -35,12 +37,16 @@ namespace GUIEditor Q_SIGNALS: void okClicked(); - + private Q_SLOTS: void onOKButtonClicked(); + void onTextEditContextMenu( const QPoint &pos ); + void onEE(); + void onEEClosing(); private: uint32 currentLinkId; + LinkEditorPvt *m_pvt; }; } diff --git a/code/studio/src/plugins/gui_editor/link_editor.ui b/code/studio/src/plugins/gui_editor/link_editor.ui index 13a6e7d7e..657b0eabc 100644 --- a/code/studio/src/plugins/gui_editor/link_editor.ui +++ b/code/studio/src/plugins/gui_editor/link_editor.ui @@ -26,6 +26,9 @@ + + Qt::CustomContextMenu +