diff --git a/CMakeLists.txt b/CMakeLists.txt index cf35ac66..fa81cd9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,38 +1,21 @@ -# PARTIO SOFTWARE -# Copyright 2010 Disney Enterprises, Inc. All rights reserved -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation -# Studios" or the names of its contributors may NOT be used to -# endorse or promote products derived from this software without -# specific prior written permission from Walt Disney Pictures. -# -# Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -# IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 ## CMake compatibility issues: don't modify this, please! -CMAKE_MINIMUM_REQUIRED( VERSION 2.4.6 ) +CMAKE_MINIMUM_REQUIRED( VERSION 2.4.6 ) MARK_AS_ADVANCED(CMAKE_BACKWARDS_COMPATIBILITY) ## allow more human readable "if then else" constructs SET( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE ) @@ -52,9 +35,12 @@ if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) +# macros +include(src/build/macros.cmake) ## Setup platform specific helper defines build variants IF(WIN32) + include (GenerateExportHeader) ADD_DEFINITIONS (-DSEEXPR_WIN32) ELSE(WIN32) ADD_DEFINITIONS (-Wall -Wextra) @@ -92,14 +78,22 @@ IF (NOT DEFINED CMAKE_INSTALL_PREFIX) SET(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/${VARIANT_DIRECTORY}-${FLAVORDIR}") ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) -## Make modules able to see partio library -# Setup environment variable to link partio +## Make modules able to see seexpr library +# Setup environment variable to link seexpr SET( SEEXPR_LIBRARIES SeExpr ) -# make it so partio can be found +SET( SEEXPR_EDITOR_LIBRARIES SeExprEditor ) +# make it so seexpr can be found INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/SeExpr ) +INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/SeExprEditor ) + +# Allowing to use lib64 +IF (NOT DEFINED CMAKE_INSTALL_LIBDIR) + SET(CMAKE_INSTALL_LIBDIR "lib") +ENDIF() ## Traverse subdirectories ADD_SUBDIRECTORY (src/SeExpr) +ADD_SUBDIRECTORY (src/SeExprEditor) ADD_SUBDIRECTORY (src/doc) ADD_SUBDIRECTORY (src/demos) ADD_SUBDIRECTORY (src/tests) diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..2263bd36 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +Copyright Disney Enterprises, Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License +and the following modification to it: Section 6 Trademarks. +deleted and replaced with: + +6. Trademarks. This License does not grant permission to use the +trade names, trademarks, service marks, or product names of the +Licensor and its affiliates, except as required for reproducing +the content of the NOTICE file. + +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 diff --git a/README b/README index a49f852f..71d8c744 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ =================================================================== -SeExr - An embeddable expression evaluation engine +SeExpr - An embeddable expression evaluation engine =================================================================== diff --git a/src/SeExpr/CMakeLists.txt b/src/SeExpr/CMakeLists.txt index b309b9af..6069ad88 100644 --- a/src/SeExpr/CMakeLists.txt +++ b/src/SeExpr/CMakeLists.txt @@ -1,94 +1,81 @@ -# SEEXPR SOFTWARE -# Copyright 2011 Disney Enterprises, Inc. All rights reserved -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation -# Studios" or the names of its contributors may NOT be used to -# endorse or promote products derived from this software without -# specific prior written permission from Walt Disney Pictures. -# -# Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -# IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -FILE(GLOB io_cpp "*.cpp") +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 -## find our parser generators -find_program(BISON_EXE bison) -find_program(FLEX_EXE flex) -find_program(SED_EXE sed) +FILE(GLOB io_cpp "*.cpp") -if((BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) - # don't have flex/bison/sed, use pregenerated versions - set (parser_cpp generated/SeExprParser.cpp generated/SeExprParserLex.cpp ) -else ((BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) - ## build the parser from the flex/yacc sources - ADD_CUSTOM_COMMAND( - SOURCE "SeExprParserLex.l" - COMMAND "flex" - ARGS "-oSeExprParserLexIn.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SeExprParserLex.l" - OUTPUT SeExprParserLexIn.cpp - DEPENDS SeExprParserLex.l - ) - - ADD_CUSTOM_COMMAND( - SOURCE "SeExprParserLexIn.cpp" - COMMAND "sed" +## find our parser generators +#find_program(BISON_EXE bison) +#find_program(FLEX_EXE flex) +#find_program(SED_EXE sed) +# +#if((BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) +# # don't have flex/bison/sed, use pregenerated versions +# set (parser_cpp generated/SeExprParser.cpp generated/SeExprParserLex.cpp ) +#else ((BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) +# ## build the parser from the flex/yacc sources +# +# ADD_CUSTOM_COMMAND( +# SOURCE "SeExprParserLex.l" +# COMMAND "flex" +# ARGS "-oSeExprParserLexIn.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/SeExprParserLex.l" +# OUTPUT SeExprParserLexIn.cpp +# DEPENDS SeExprParserLex.l +# ) +# +# ADD_CUSTOM_COMMAND( +# SOURCE "SeExprParserLexIn.cpp" +# COMMAND "sed" +## ARGS -e "'s/SeExprwrap(n)/SeExprwrap()/g'" -e "'s/yy/SeExpr/g'" -e "'s/YY/SeExprYY/g'" SeExprParserLexIn.cpp | tee SeExprParserLex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/generated/SeExprParserLex.cpp > /dev/null # ARGS -e "'s/SeExprwrap(n)/SeExprwrap()/g'" -e "'s/yy/SeExpr/g'" -e "'s/YY/SeExprYY/g'" SeExprParserLexIn.cpp | tee SeExprParserLex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/generated/SeExprParserLex.cpp > /dev/null - ARGS -e "'s/SeExprwrap(n)/SeExprwrap()/g'" -e "'s/yy/SeExpr/g'" -e "'s/YY/SeExprYY/g'" SeExprParserLexIn.cpp | tee SeExprParserLex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/generated/SeExprParserLex.cpp > /dev/null - OUTPUT SeExprParserLex.cpp - DEPENDS SeExprParserLexIn.cpp - ) - - ADD_CUSTOM_COMMAND( - SOURCE "SeExprParser.y" - COMMAND "bison" - ARGS "--defines" "--verbose" "--fixed-output-files" "-p" "SeExpr" "${CMAKE_CURRENT_SOURCE_DIR}/SeExprParser.y" - OUTPUT y.tab.c y.tab.h - DEPENDS SeExprParser.y - ) - - ADD_CUSTOM_COMMAND( - SOURCE "y.tab.h" - COMMAND "sed" - ARGS -e "'s/yy/SeExpr/g'" -e "'s/YY/SeExprYY/g'" y.tab.h | tee SeExprParser.tab.h ${CMAKE_CURRENT_SOURCE_DIR}/generated/SeExprParser.tab.h > /dev/null - OUTPUT SeExprParser.tab.h - DEPENDS y.tab.h - ) - - ADD_CUSTOM_COMMAND( - SOURCE "y.tab.c" - COMMAND "sed" - ARGS -e "'s/yy/SeExpr/g'" -e "'s/YY/SeExprYY/g'" y.tab.c | tee SeExprParser.cpp "${CMAKE_CURRENT_SOURCE_DIR}/generated/SeExprParser.cpp" > /dev/null - OUTPUT SeExprParser.cpp - DEPENDS y.tab.c SeExprParser.tab.h - ) +# OUTPUT SeExprParserLex.cpp +# DEPENDS SeExprParserLexIn.cpp +# ) +# +# ADD_CUSTOM_COMMAND( +# SOURCE "SeExprParser.y" +# COMMAND "bison" +# ARGS "--defines" "--verbose" "--fixed-output-files" "-p" "SeExpr" "${CMAKE_CURRENT_SOURCE_DIR}/SeExprParser.y" +# OUTPUT y.tab.c y.tab.h +# DEPENDS SeExprParser.y +# ) +# +# ADD_CUSTOM_COMMAND( +# SOURCE "y.tab.h" +# COMMAND "sed" +# ARGS -e "'s/yy/SeExpr/g'" -e "'s/YY/SeExprYY/g'" y.tab.h | tee SeExprParser.tab.h ${CMAKE_CURRENT_SOURCE_DIR}/generated/SeExprParser.tab.h > /dev/null +# OUTPUT SeExprParser.tab.h +# DEPENDS y.tab.h +# ) +# +# ADD_CUSTOM_COMMAND( +# SOURCE "y.tab.c" +# COMMAND "sed" +# ARGS -e "'s/yy/SeExpr/g'" -e "'s/YY/SeExprYY/g'" y.tab.c | tee SeExprParser.cpp "${CMAKE_CURRENT_SOURCE_DIR}/generated/SeExprParser.cpp" > /dev/null +# OUTPUT SeExprParser.cpp +# DEPENDS y.tab.c SeExprParser.tab.h +# ) +# +# ## set build files +# set (parser_cpp SeExprParser.cpp SeExprParserLex.cpp ) +# +#endif( (BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) - ## set build files - set (parser_cpp SeExprParser.cpp SeExprParserLex.cpp ) +BuildParserScanner(SeExprParserLex SeExprParser SeExpr parser_cpp) -endif( (BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) ## Make the SeExpr library ADD_LIBRARY (SeExpr SHARED ${io_cpp} ${core_cpp} ${parser_cpp}) @@ -102,8 +89,5 @@ IF(NOT WIN32) ENDIF(NOT WIN32) ## Install binary and includes FILE(GLOB public_includes "*.h") -IF (NOT DEFINED CMAKE_INSTALL_LIBDIR) - SET(CMAKE_INSTALL_LIBDIR "lib") -ENDIF (NOT DEFINED CMAKE_INSTALL_LIBDIR) INSTALL (TARGETS SeExpr SeExpr-static DESTINATION ${CMAKE_INSTALL_LIBDIR}) INSTALL (FILES ${public_includes} DESTINATION include) diff --git a/src/SeExpr/SeCurve.cpp b/src/SeExpr/SeCurve.cpp index 19b50126..d4964c21 100644 --- a/src/SeExpr/SeCurve.cpp +++ b/src/SeExpr/SeCurve.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #include "SeExpression.h" #include "SeExprBuiltins.h" diff --git a/src/SeExpr/SeCurve.h b/src/SeExpr/SeCurve.h index 2a827a8c..030ab03b 100644 --- a/src/SeExpr/SeCurve.h +++ b/src/SeExpr/SeCurve.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef _CurveData_h_ #define _CurveData_h_ diff --git a/src/SeExpr/SeExprBuiltins.cpp b/src/SeExpr/SeExprBuiltins.cpp index ebf5e8b4..ff8fc070 100644 --- a/src/SeExpr/SeExprBuiltins.cpp +++ b/src/SeExpr/SeExprBuiltins.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #define __STDC_LIMIT_MACROS diff --git a/src/SeExpr/SeExprBuiltins.h b/src/SeExpr/SeExprBuiltins.h index c357162f..d83907b0 100644 --- a/src/SeExpr/SeExprBuiltins.h +++ b/src/SeExpr/SeExprBuiltins.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef SeExprBuiltins_h diff --git a/src/SeExpr/SeExprFunc.cpp b/src/SeExpr/SeExprFunc.cpp index feb6b450..93a9f061 100644 --- a/src/SeExpr/SeExprFunc.cpp +++ b/src/SeExpr/SeExprFunc.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #include #include diff --git a/src/SeExpr/SeExprFunc.h b/src/SeExpr/SeExprFunc.h index fc46c5b6..9461eff0 100644 --- a/src/SeExpr/SeExprFunc.h +++ b/src/SeExpr/SeExprFunc.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef SeExprFunc_h #define SeExprFunc_h diff --git a/src/SeExpr/SeExprMacros.h b/src/SeExpr/SeExprMacros.h new file mode 100644 index 00000000..008b3981 --- /dev/null +++ b/src/SeExpr/SeExprMacros.h @@ -0,0 +1,24 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ + +#ifndef SeExprMacros_h +#define SeExprMacros_h + +#define UNUSED(x) (void)(x) + +#endif + diff --git a/src/SeExpr/SeExprNode.cpp b/src/SeExpr/SeExprNode.cpp index 77066304..2a840e1c 100644 --- a/src/SeExpr/SeExprNode.cpp +++ b/src/SeExpr/SeExprNode.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ /* Parse tree nodes - this is where the expression evaluation happens. diff --git a/src/SeExpr/SeExprNode.h b/src/SeExpr/SeExprNode.h index 337c30c9..1e0070a6 100644 --- a/src/SeExpr/SeExprNode.h +++ b/src/SeExpr/SeExprNode.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef SeExprNode_h diff --git a/src/SeExpr/SeExprParser.h b/src/SeExpr/SeExprParser.h index 623b01c0..14335b2b 100644 --- a/src/SeExpr/SeExprParser.h +++ b/src/SeExpr/SeExprParser.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef SeExprParser_h #define SeExprParser_h diff --git a/src/SeExpr/SeExprParser.y b/src/SeExpr/SeExprParser.y index 9a74fa1c..02cbc19e 100644 --- a/src/SeExpr/SeExprParser.y +++ b/src/SeExpr/SeExprParser.y @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ %{ @@ -190,7 +172,6 @@ assign: | NAME ModEq e ';' {SeExprNode* varNode=NODE1(@1.first_column,@1.first_column,VarNode, $1); SeExprNode* opNode=NODE2(@3.first_column,@3.first_column,ModNode,varNode,$3); $$ = NODE2(@$.first_column,@$.last_column,AssignNode, $1, opNode);} - | ; ifthenelse: diff --git a/src/SeExpr/SeExprParserLex.l b/src/SeExpr/SeExprParserLex.l index 9f84f70d..d611507b 100644 --- a/src/SeExpr/SeExprParserLex.l +++ b/src/SeExpr/SeExprParserLex.l @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ /* Don't generate yywrap since everything is in one string */ diff --git a/src/SeExpr/SeExpression.cpp b/src/SeExpr/SeExpression.cpp index 0beff25d..113ba898 100644 --- a/src/SeExpr/SeExpression.cpp +++ b/src/SeExpr/SeExpression.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef MAKEDEPEND #include @@ -145,6 +127,7 @@ SeExpression::prep() const parseIfNeeded(); if (_parseTree && !_parseTree->prep(wantVec())) { // build line lookup table + // contains position of last char in line, from the very beginning std::vector lines; const char* start=_expression.c_str(); const char* p=_expression.c_str(); @@ -157,8 +140,13 @@ SeExpression::prep() const std::stringstream sstream; sstream<<"Prep errors:"<::iterator bound=lower_bound(lines.begin(), + lines.end(), + _errors[i].startPos); + int line=&*bound-&*lines.begin()+1; //int column=_errors[i].startPos-lines[line-1]; sstream<<" Line "< #include #include +#include #include "SeVec3d.h" class SeExprNode; diff --git a/src/SeExpr/SeMutex.h b/src/SeExpr/SeMutex.h index 01cbe731..f2b9f629 100644 --- a/src/SeExpr/SeMutex.h +++ b/src/SeExpr/SeMutex.h @@ -1,36 +1,18 @@ /* -SEEXPR SOFTWARE -Copyright 2011 Disney Enterprises, Inc. All rights reserved - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - -Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef SeMutex_h #define SeMutex_h diff --git a/src/SeExpr/SeNoise.cpp b/src/SeExpr/SeNoise.cpp index cf8dbf55..55454f78 100644 --- a/src/SeExpr/SeNoise.cpp +++ b/src/SeExpr/SeNoise.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #include diff --git a/src/SeExpr/SeNoise.h b/src/SeExpr/SeNoise.h index 62c53ae5..67a46cd5 100644 --- a/src/SeExpr/SeNoise.h +++ b/src/SeExpr/SeNoise.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef _noise_h_ #define _noise_h_ diff --git a/src/SeExpr/SeNoiseTables.h b/src/SeExpr/SeNoiseTables.h index 98fff90c..b74b610a 100644 --- a/src/SeExpr/SeNoiseTables.h +++ b/src/SeExpr/SeNoiseTables.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef _SeNoiseTables_h_ #define _SeNoiseTables_h_ diff --git a/src/SeExpr/SePlatform.h b/src/SeExpr/SePlatform.h index 32a6b963..a96f3d15 100644 --- a/src/SeExpr/SePlatform.h +++ b/src/SeExpr/SePlatform.h @@ -1,36 +1,18 @@ /* -SEEXPR SOFTWARE -Copyright 2011 Disney Enterprises, Inc. All rights reserved - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - -Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef SePlatform_h #define SePlatform_h diff --git a/src/SeExpr/SeVec3d.h b/src/SeExpr/SeVec3d.h index 94c2b99b..9305c2cb 100644 --- a/src/SeExpr/SeVec3d.h +++ b/src/SeExpr/SeVec3d.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef SeVec3d_h diff --git a/src/SeExprEditor/CE/CECurveListUI.cpp b/src/SeExprEditor/CE/CECurveListUI.cpp new file mode 100644 index 00000000..860404ba --- /dev/null +++ b/src/SeExprEditor/CE/CECurveListUI.cpp @@ -0,0 +1,184 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CECurveListUI.cpp +* @brief Contains the Definition of class CECurveListUI. +*/ + +/*qt3 +#include +#include +#include +*/ + +#include +#include +#include +#include +#include + +#include "CETool.h" +#include "CECurveListUI.h" + +/** + * Constructor. + */ +CECurveListUI::CECurveListUI(QWidget* parent, CETool* tool) : + QWidget(parent), _tool(tool), + _listValid(0), _selValid(0), _updating(0) +{ + setObjectName("CurveList"); + + QVBoxLayout* layout = new QVBoxLayout(this); +//qt3 layout->setAutoAdd(true); + + QLabel* label = new QLabel("Curves", this); + _list = new QListWidget(this); + _list->setSelectionMode(QAbstractItemView::ExtendedSelection); + + layout->addWidget(label); + layout->addWidget(_list); + + connect(_tool, SIGNAL(curveListChanged()), SLOT(invalidateCurveList())); + connect(_tool, SIGNAL(selectionChanged()), SLOT(invalidateSelection())); + connect(_list, SIGNAL(itemSelectionChanged()), SLOT(handleSelectionChanged())); + + doUpdate(); +} + +/** + * Destructor. + */ +CECurveListUI::~CECurveListUI() +{ +} + + +void +CECurveListUI::invalidateCurveList() +{ + if (_listValid || _selValid) { + _listValid = 0; + _selValid = 0; + update(); + } +} + + +void +CECurveListUI::invalidateSelection() +{ + if (_updating) return; // prevent circular update! + if (_selValid) { + _selValid = 0; + update(); + } +} + + +void +CECurveListUI::paintEvent(QPaintEvent* event) +{ + if (!_listValid || !_selValid) doUpdate(); + QWidget::paintEvent(event); +} + + +void +CECurveListUI::showEvent(QShowEvent* event) +{ + if (!_listValid || !_selValid) doUpdate(); + QWidget::showEvent(event); +} + + +void +CECurveListUI::doUpdate() +{ + _updating = 1; + + if (!_listValid) { + // update listbox contents from tool + std::vector names; + _tool->getCurveNames(names); + int i; + for (i = 0; i < (int)names.size(); i++) { + const char* name = names[i].c_str(); + if (i >= (int) _list->count()) + _list->addItem(name); +//qt3 else if (_list->text(i) != name) + else if (_list->currentItem() && + _list->currentItem()->text() != name) + { +//qt3 _list->changeItem(name, i); + QListWidgetItem* curItem = _list->currentItem(); + curItem->setText(name); + } + } + while ((int) _list->count() > i) +//qt3 _list->removeItem(_list->count()-1); + _list->takeItem( _list->count()-1 ); + + } + if (!_listValid || !_selValid) { + // update listbox's selection from tool + msg::list sel; + _tool->getSelection(sel); + _list->clearSelection(); // TODO: will this emit selectionChanged() like the Qt3 version? + for (int i = 0; i < sel.size(); i+=2) +//qt3 _list->setSelected(sel[i], true); + _list->setCurrentRow(sel[i]); // TODO: I'm pretty sure sel[i] will be an int + } + _selValid = 1; + _listValid = 1; + _updating = 0; +} + +void +CECurveListUI::handleSelectionChanged() +{ + if (_updating) return; // prevent circular update! + _updating = 1; + + // first count selections + int num = 0; + int curve=0; + int i; + for (i = 0; i < (int) _list->count(); i++) + { + QListWidgetItem* curItem = _list->item(i); +//qt3 if (_list->isSelected(i)) { num++; curve = i; } + if ( curItem && curItem->isSelected() ) { num++; curve = i; } + } + + // update tool's selection list from listbox + if (num == 0) + _tool->clearSelection(); + else if (num == 1) + _tool->selectCurve(curve); + else { + msg::list selections(num); + int n = 0; + for (i = 0; i < (int) _list->count(); i++) + { +//qt3 if (_list->isSelected(i)) + QListWidgetItem* curItem = _list->item(i); + if (curItem->isSelected()) selections.set(n++, i); + } + _tool->selectCurves(selections); + } + _updating = 0; +} diff --git a/src/SeExprEditor/CE/CECurveListUI.h b/src/SeExprEditor/CE/CECurveListUI.h new file mode 100644 index 00000000..cb418f75 --- /dev/null +++ b/src/SeExprEditor/CE/CECurveListUI.h @@ -0,0 +1,82 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CECurveListUI.h +* @brief Contains the declaration of class CECurveListUI. +*/ + +#ifndef CECurveListUI_h +#define CECurveListUI_h + +//qt3 #include +#include + +class CETool; +class QListWidget; + + +//**************************************************************************** +/** + * @class CECurveListUI + * @brief User interface for the Curve Editor's Curve list UI + * + * Insert detailed description of class CECurveListUI definition here. + * + * @author brentb + * + * @version 1.0 brentb 11/20/2001: Initial version of class CECurveListUI. + * + */ + +class CECurveListUI : public QWidget +{ + Q_OBJECT + +public: + /// Constructor + CECurveListUI(QWidget* parent, CETool* tool); + /// Destructor + virtual ~CECurveListUI(); + + /// override of minimumSizeHint + virtual QSize minimumSizeHint () const { return QSize(0,0); } + +private slots: + + void invalidateCurveList(); + void invalidateSelection(); + void handleSelectionChanged(); + +private: + /// No definition by design, so accidental copying is prevented. + CECurveListUI ( const CECurveListUI& ); + /// No definition by design, so accidental assignment is prevented. + CECurveListUI& operator=( const CECurveListUI& ); + /// QWidget override + virtual void paintEvent (QPaintEvent* event); + virtual void showEvent (QShowEvent* event); + + /// Update state from tool/curve data + void doUpdate(); + + CETool* _tool; + QListWidget* _list; + bool _listValid; + bool _selValid; + bool _updating; +}; + +#endif //CECurveListUI_h diff --git a/src/SeExprEditor/CE/CEDragHandlers.cpp b/src/SeExprEditor/CE/CEDragHandlers.cpp new file mode 100644 index 00000000..0cdefcea --- /dev/null +++ b/src/SeExprEditor/CE/CEDragHandlers.cpp @@ -0,0 +1,387 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include +//#include +#include "CETool.h" +#include "CEGraphUI.h" +#include "CEGraphCurve.h" +#include "CEGraphSeg.h" +#include "CEGraphKey.h" +#include "CEDragHandlers.h" + + +static double RoundNicely(double val, double inc) +{ + // first make inc nice (i.e. [1, 2, or 5] * some power of 10) + double nice = pow(10, floor(log10(inc))); + if (nice < inc) + { + nice *= 2; + if (nice < inc) + { + nice *= 2.5; + if (nice < inc) + { + nice *= 2; + } + } + } + + // round val to nearest multiple of inc + return floor(val/nice+.5)*nice; +} + + +void CEDragHandler::setAnchor(CEGraphUI* ui, int x, int y) +{ + _ui = ui; + _anchorX = _x = x; + _anchorY = _y = y; + _view = _ui->getView(); + _dx = _dy = 0; +} + + +void CEDragHandler::movePoint(int x, int y) +{ + _x = x; + _y = y; + _dx = _x - _anchorX; + _dy = _y - _anchorY; + _moved = true; +} + + + +void CEPanHandler::pan(bool useCommand) +{ + double x = _view.vx() - _dx*_view.pixelWidth(); + double y = _view.vy() - _dy*_view.pixelHeight(); + double w = _view.vw(), h = _view.vh(); + + _ui->tool()->setView(x, y, w, h); +} + + +void CEZoomHandler::zoom(bool useCommand) +{ + double sx = 1, sy = 1; + if (_zoomX) { + double dx = _dx; + sx = dx < 0 ? (1 - dx/100.0) : 1 / (1 + dx/100.0); + } + + if (_zoomY) { + double dy = _dy; + sy = dy < 0 ? (1 - dy/100.0) : 1 / (1 + dy/100.0); + } + + double x = _view.vx(), y = _view.vy(); + double w = _view.vw()*sx, h = _view.vh()*sy; + + _ui->tool()->setView(x, y, w, h); +} + + +void CESelBoxHandler::mouseMove() +{ + _ui->moveSelBox(_anchorX, _anchorY, _x, _y); + + // do a select-mode render to get the pending segments + static const int buffsize = 10000; + GLuint selbuff[buffsize]; + int numHits = _ui->doSelectModeRender(_anchorX, _x, _anchorY, _y, + selbuff, buffsize); + std::vector newsegs; + GLuint* p = selbuff; + for (int i = 0; i < numHits; i++) + { + GLuint numNames = p[0]; p+=3; + if (numNames >= 3) { + if (p[2] == CEGraphSeg::Key) { + newsegs.push_back(Seg(p[0], p[1])); + } + } + p += numNames; + } + + if (_segs != newsegs) + { + SegIterator i; + for (i = _segs.begin(); i != _segs.end(); i++) { + CEGraphSeg* seg = _ui->getSeg(i->curveIndex, i->segIndex); + if (seg) seg->setPendingSel(0); + } + + _segs = newsegs; + for (i = _segs.begin(); i != _segs.end(); i++) { + CEGraphSeg* seg = _ui->getSeg(i->curveIndex, i->segIndex); + if (seg) seg->setPendingSel(1); + } + + _ui->update(); + } +} + + +void CESelBoxHandler::mouseUp() +{ + _ui->hideSelBox(); + //iCurveEditor& ce = _ui->ce(); + CETool* tool=_ui->tool(); + SegIterator i; + for (i = _segs.begin(); i != _segs.end(); i++) + { + CEGraphSeg* seg = _ui->getSeg(i->curveIndex, i->segIndex); + + if (seg && seg->isPendingSel()) + { + seg->setPendingSel(0); + + bool selected = 0; + if (_toggle) + tool->isSegmentSelected(selected, i->curveIndex, i->segIndex); + if (selected) + tool->deselectSegment(i->curveIndex, i->segIndex); + else + tool->selectAddSegment(i->curveIndex, i->segIndex); + } + } + +} + + +CEKeyHandler::CEKeyHandler(CEGraphKey* key) +{ + _animCurve = &key->curve()->animCurve(); + _curve = key->curve()->index(); + _seg = key->index(); +} + + +CEKeyMoveHandler::CEKeyMoveHandler(CEGraphKey* key, bool dragTime, bool dragValue, + double hSnap, double vSnap) + : CEKeyHandler(key), _dragTime(dragTime), _dragValue(dragValue), + _hSnap(hSnap), _vSnap(vSnap) +{ + _anchorTime = key->key().getTime(); + _anchorValue = key->key().getValue(); +} + + + +void CEKeyMoveHandler::setMultiDrag(std::vector graph_segments) +{ + for (unsigned int i = 0; i < graph_segments.size(); i++) + { + CEGraphKey* segment = graph_segments[i]; + _anchorTimes.push_back(segment->key().getTime()); + _anchorValues.push_back(segment->key().getValue()); + _curves.push_back(segment->curve()->index()); + _segs.push_back(segment->index()); + } +} + + +void CEKeyMoveHandler::moveKey(bool useCommand) +{ + + if (_anchorTimes.size() >0) + { + //We are doing Multi-Drag! + for (unsigned int i = 0; i < _anchorTimes.size(); i++) + { + if (_dragTime) + { + double newtime = _anchorTimes[i] + _dx*_view.pixelWidth(); + double snap = _view.pixelWidth(); + if (snap < _hSnap) snap = _hSnap; + newtime = RoundNicely(newtime, snap); + CEGraphSeg* prevseg = _ui->getSeg(_curves[i], _segs[i]-1); + CEGraphSeg* nextseg = _ui->getSeg(_curves[i], _segs[i]+1); + if (prevseg && !prevseg->firstSeg() && newtime < prevseg->keyTime()) + newtime = prevseg->keyTime(); + if (nextseg && newtime > nextseg->keyTime()) + newtime = nextseg->keyTime(); + _ui->tool()->setSegmentFrame(newtime, _curves[i], _segs[i]); + } + if (_dragValue) + { + double newval = _anchorValues[i] + _dy*_view.pixelHeight(); + double snap = _view.pixelHeight(); + if (snap < _vSnap) snap = _vSnap; + newval = RoundNicely(newval, snap); + + _ui->tool()->setSegmentValue(newval, _curves[i], _segs[i]); + } + } + } + else + { + //Only dragging one key + if (_dragTime) + { + double newtime = _anchorTime + _dx*_view.pixelWidth(); + double snap = _view.pixelWidth(); + if (snap < _hSnap) snap = _hSnap; + newtime = RoundNicely(newtime, snap); + CEGraphSeg* prevseg = _ui->getSeg(_curve, _seg-1); + CEGraphSeg* nextseg = _ui->getSeg(_curve, _seg+1); + if (prevseg && !prevseg->firstSeg() && newtime < prevseg->keyTime()) + newtime = prevseg->keyTime(); + if (nextseg && newtime > nextseg->keyTime()) + newtime = nextseg->keyTime(); + _ui->tool()->setSelectedSegmentFrame(newtime); + } + if (_dragValue) + { + double newval = _anchorValue + _dy*_view.pixelHeight(); + double snap = _view.pixelHeight(); + if (snap < _vSnap) snap = _vSnap; + newval = RoundNicely(newval, snap); + _ui->tool()->setSelectedSegmentValue(newval); + } + } +} + + +void CENewKeyHandler::mouseDown() +{ + //_dragTime = _dragValue = 1; + double snap = _view.pixelWidth(); + if (snap < 0) snap = 0; + double _anchorTime = RoundNicely(_view.vx(_x), snap); + double _anchorValue = RoundNicely(_view.vy(_y), _view.pixelHeight()); + int index=0; + _ui->tool()->insertKey(_anchorTime); +} + + + CEBezHandler::CEBezHandler(CEGraphKey* key, int handle, + bool dragAngle, bool dragLength,bool weighted) + : CEKeyHandler(key), _handle(handle), + _dragAngle(dragAngle), _dragLength(dragLength), _weighted(weighted) + { + // lookup key parametersweights and angles + _originalWeightIn=key->key().getInWeight(); + _originalWeightOut=key->key().getOutWeight(); + if(!_weighted) _originalWeightIn=_originalWeightOut=3; + _time=key->key().getTime(); + _value=key->key().getValue(); + } + + static bool ClampBezHandle(double& x1, double x2, double seglen) + { + /* Clamp handle a against handle b: + For a normalized segment (seglen = 1), two handle are at their max + length when the following relationship is true: + + a = 1 - 0.5 * (b - sqrt(b * (4 - 3 * b))) + + This equation was derived by solving for coincident real roots + of the deriviate of the bezier equation. */ + + // normalize ref handle to 0..1 + double b = x2 / seglen; + + // make sure b is legal (i.e. within 0..4/3) + if (b < 0) b = 0; + else if (b > 4/3.) b = 4/3.; + + // compute max length for input handle for given ref handle + double a = 1 - 0.5 * (b - sqrt(b * (4 - 3 * b))); + + // scale handle back to seglen (un-normalize) + a *= seglen; + + // clamp input handle (if needed) + if (x1 > a) { + x1 = a; + return true; // clamped + } + return false; // not clamped + } + +void CEBezHandler::mouseDown(){ + // remember a reference point in view coordinates where the user started interacting + double scale=_handle==0 ? -1. : 1.; + _refX=scale*(_view.vx(_x)-_time); + _refY=scale*(_view.vy(_y)-_value); +} + + void CEBezHandler::dragHandle(bool useCommand) + { + CEGraphKey* key = _ui->getKey(_curve, _seg); + if(_handle != 0 && _handle != 1) return; + + double pw = _view.pixelWidth(); + double ph = _view.pixelHeight(); + double dx = _dx * pw; + double dy = _dy * ph; + if(_handle == 0){dx=-dx;dy=-dy;} + //std::cerr<<"we have _dx "<<_dx<<" "<<_dy<<" dx "<outTime() - seg->keyTime(); + + // the new weight is the length of the new offset + double nweight=sqrt(ny*ny+nx*nx); + + // figure out angles and clamp to be vertical + double na = atan2(ny, nx); + if(na > M_PI_2) na = M_PI_2; + if(na < -M_PI_2) na = -M_PI_2; + + // TODO: clamp handle in non-weighted case + double inWeight=nweight; + double outWeight=nweight; + if(!_dragLength){ + inWeight=_originalWeightIn; + outWeight=_originalWeightOut; + } + if(!key->weighted()){ + double prevTime=0,nextTime=0; + if(CEGraphKey* prevKey=_ui->getKey(_curve,_seg-1)) + prevTime=prevKey->key().getTime(); + if(CEGraphKey* nextKey=_ui->getKey(_curve,_seg+1)) + nextTime=nextKey->key().getTime(); + double currTime=key->key().getTime(); + // cos(na) = xlength / weight + // we want xlength = (timeInterval) / 3 + // so weight = xlength / cos(na) + outWeight=((nextTime-currTime)/3.)/cos(na); + inWeight=((currTime-prevTime)/3.)/cos(na); + } + // if we are weighted keep and we are locked we want old weight for + // the matched guy + if(key->weighted()){ + if(_handle==0) outWeight=_originalWeightOut; + if(_handle==1) inWeight=_originalWeightIn; + } + // set if we are locked or if it is our handle + if(_handle==0 || key->key().isLocked()) + _ui->tool()->setKeyIn(_curve,_seg,na*180./M_PI,inWeight); + if(_handle==1 || key->key().isLocked()) + _ui->tool()->setKeyOut(_curve,_seg,na*180./M_PI,outWeight); + + } diff --git a/src/SeExprEditor/CE/CEDragHandlers.h b/src/SeExprEditor/CE/CEDragHandlers.h new file mode 100644 index 00000000..5f807f43 --- /dev/null +++ b/src/SeExprEditor/CE/CEDragHandlers.h @@ -0,0 +1,168 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef CEDragHandlers_h +#define CEDragHandlers_h + +#include +//#include +#include "CEGraphView.h" +#include + +class CEGraphUI; +class CETool; +class CEGraphSeg; + +class CEDragHandler +{ +public: + CEDragHandler() : _moved(false), _anchorX(0), _anchorY(0), _x(0), _y(0), + _dx(0), _dy(0), _ui(0) {} + virtual ~CEDragHandler() {} + + virtual void mouseDown() {} + virtual void mouseMove() {} + virtual void mouseUp() {} + virtual bool showCrossHairs() { return 0; } + virtual void setMultiDrag(std::vector graph_segments) {} + + void setAnchor(CEGraphUI* ui, int anchorX, int anchorY); + void movePoint(int x, int y); + +protected: + bool _moved; + int _anchorX, _anchorY; // mouse down x,y pos + int _x, _y; // current x,y pos + int _dx, _dy; // delta x,y (current-anchor) for convenience + CEGraphView _view; // view at mouse down + CEGraphUI* _ui; // graph ui +}; + + +class CEPanHandler : public CEDragHandler +{ +public: + virtual void mouseMove() { pan(false); } + virtual void mouseUp() { if (_moved) pan(true); } +private: + void pan(bool useCommand); +}; + + +class CEZoomHandler : public CEDragHandler +{ +public: + CEZoomHandler(bool x, bool y) : _zoomX(x), _zoomY(y) {} + virtual void mouseMove() { zoom(false); } + virtual void mouseUp() { if (_moved) zoom(true); } +private: + void zoom(bool useCommand); + bool _zoomX; // flag enabling x zooming + bool _zoomY; // flag enabling y zooming +}; + + +class CESelBoxHandler : public CEDragHandler +{ +public: + CESelBoxHandler(bool toggle) : _toggle(toggle) {} + virtual void mouseMove(); + virtual void mouseUp(); +private: + bool _toggle; + struct Seg { + Seg(int curveIndex, int segIndex) + : curveIndex(curveIndex), segIndex(segIndex) {} + bool operator==(const Seg& seg) const + { return curveIndex==seg.curveIndex && segIndex==seg.segIndex; } + bool operator!=(const Seg& seg) const + { return curveIndex!=seg.curveIndex || segIndex!=seg.segIndex; } + int curveIndex; + int segIndex; + }; + typedef std::vector::iterator SegIterator; + std::vector _segs; +}; + + +class CEKeyHandler : public CEDragHandler +{ +public: + CEKeyHandler(CEGraphKey* seg); + virtual bool showCrossHairs() { return 1; } + +protected: + animlib::AnimCurve* _animCurve; + int _curve; // curve index + int _seg; // segment index + +}; + + +class CEKeyMoveHandler : public CEKeyHandler +{ +public: + CEKeyMoveHandler(CEGraphKey* key, bool dragTime, bool dragValue, + double hSnap=0, double vSnap=0); + virtual void mouseMove() { moveKey(false); } + virtual void mouseUp() { if (_moved) moveKey(true); } + virtual void setMultiDrag(std::vector graph_segments); +protected: + void moveKey(bool useCommand); + bool _dragTime; + bool _dragValue; + double _anchorTime; + double _anchorValue; + std::vector _anchorTimes; //Mutiple segments only + std::vector _anchorValues; //Mutiple segments only + std::vector _curves; //Mutiple segments only + std::vector _segs; //Mutiple segments only + double _hSnap; + double _vSnap; +}; + + +class CENewKeyHandler :public CEDragHandler +{ +public: + CENewKeyHandler(CEGraphSeg* key) + :_key(key) + {} + virtual void mouseDown(); + +private: + CEGraphSeg* _key; +}; + + +class CEBezHandler : public CEKeyHandler +{ +public: + CEBezHandler(CEGraphKey* key, int handle, bool dragAngle, bool dragLength, bool weighted); + virtual void mouseMove() { dragHandle(false); } + virtual void mouseUp() { if (_moved) dragHandle(true); } + virtual void mouseDown(); + void dragHandle(bool useCommand); + +protected: + int _handle; + bool _dragAngle, _dragLength; + bool _weighted; + double _refX, _refY; // reference point where we started dragging from + double _originalWeightIn,_originalWeightOut; // original weights + double _time,_value; +}; +#endif diff --git a/src/SeExprEditor/CE/CEGraphCurve.cpp b/src/SeExprEditor/CE/CEGraphCurve.cpp new file mode 100644 index 00000000..b563820c --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphCurve.cpp @@ -0,0 +1,158 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include +#include +#include "CETool.h" +#include "CEGraphUI.h" +#include "CEDragHandlers.h" +#include "CEGraphCurve.h" +#include "CEGraphSeg.h" +#include "CEGraphKey.h" + + +CEGraphCurve::CEGraphCurve(CEGraphUI* ui, animlib::AnimCurve* curveData, int index) + : _ui(ui), _animCurve(curveData),_index(index), _segsValid(0), _viewValid(0), + _firstSegInView(0), _lastSegInView(0) +{ +} + + +CEGraphCurve::~CEGraphCurve() +{ + clearSegs(); +} + + +void +CEGraphCurve::clearSegs() +{ + for (int i = 0; i < (int) _segs.size(); i++) { + delete _segs[i].seg; + delete _segs[i].key; + } + _segs.clear(); + _viewValid = 0; +} + + +void +CEGraphCurve::invalidate() +{ + if (_segsValid) _segsValid = 0; +} + + +void +CEGraphCurve::invalidateView() +{ + _viewValid = 0; +} + + + +void +CEGraphCurve::paint(bool selected) +{ + if (!_segsValid) buildSegPtrs(); + if (!_viewValid) updateView(); + + glPushName(_index); + // paint segs, keys, handles + for (int i = _firstSegInView; i <= _lastSegInView; i++) { + CEGraphSeg* seg=0;CEGraphKey* key=0; + getSegAndKey(i,seg,key) ; + if(seg) seg->paint(selected); + if(key) key->paint(selected); + } + glPopName(); +} + + +int +CEGraphCurve::numSegs() +{ + if (!_segsValid) buildSegPtrs(); + return _segs.size(); +} + + +void +CEGraphCurve::getSegAndKey(int n,CEGraphSeg*& seg,CEGraphKey*& key) +{ + if (!_segsValid) buildSegPtrs(); + if (n < 0 || n >= (int) _segs.size()){ + seg=0; + key=0; + return; + }; + seg = _segs[n].seg; + key = _segs[n].key; + if(!seg) seg=_segs[n].seg = new CEGraphBezSeg(this,n); + if(!key) key=_segs[n].key = new CEGraphKey(this,n); +} + + +void +CEGraphCurve::buildSegPtrs() +{ + clearSegs(); + + // build seg info list + int numSegs=_animCurve->getNumKeys(); + _segs.resize(numSegs); + _segsValid = 1; +} + + +void +CEGraphCurve::buildSeg(int n) +{ + if (n < 0 || n > (int) _segs.size()) return; + if (_segs[n].seg) { delete _segs[n].seg; _segs[n].seg = 0; } + +} + + +void +CEGraphCurve::updateView() +{ + + const CEGraphView& view = _ui->getView(); + _firstSegInView=0; + _lastSegInView=numSegs()-1; + // TODO: make this as adaptive as before + //if (!_expr.findSegment(_firstSegInView, view.left(), false).ok()) return; + //if (!_expr.findSegment(_lastSegInView, view.right()).ok()) return; + + if (_segsValid) { + for (int i = _firstSegInView; i <= _lastSegInView; i++) { + if (auto seg = _segs[i].seg) + seg->invalidateView(); + } + } + _viewValid = 1; +} + + + + + + + + + + diff --git a/src/SeExprEditor/CE/CEGraphCurve.h b/src/SeExprEditor/CE/CEGraphCurve.h new file mode 100644 index 00000000..71eb85f6 --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphCurve.h @@ -0,0 +1,69 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef CEGraphCurve_h +#define CEGraphCurve_h + +#include +#include + +#include + +class CETool; +class CEGraphUI; +class CEGraphSeg; +class CEGraphKey;; + + +class CEGraphCurve +{ +public: + CEGraphCurve(CEGraphUI* ui, animlib::AnimCurve* data, int index); + ~CEGraphCurve(); + CEGraphUI* ui() { return _ui; } + animlib::AnimCurve& animCurve() { return *_animCurve; } + int index() { return _index; } + void paint(bool selected); + void invalidate(); + void invalidateView(); + int numSegs(); + void getSegAndKey(int segIndex,CEGraphSeg*& seg,CEGraphKey*& key); + int firstSegInView() { return _firstSegInView; } + int lastSegInView() { return _lastSegInView; } + +private: + void clearSegs(); + void buildSegPtrs(); + void buildSeg(int n); + void updateView(); + CEGraphUI* _ui; + animlib::AnimCurve* _animCurve; + //iSgExpr _expr; + int _index; // curve index within graph ui + + bool _segsValid; + bool _viewValid; + + struct SegPtr { + SegPtr() : seg(0),key(0) {} + CEGraphSeg* seg; // segment built lazily in getSeg() + CEGraphKey* key; // segment built lazily in getSeg() + }; + std::vector _segs; + int _firstSegInView; + int _lastSegInView; +}; +#endif diff --git a/src/SeExprEditor/CE/CEGraphKey.cpp b/src/SeExprEditor/CE/CEGraphKey.cpp new file mode 100644 index 00000000..b10cf862 --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphKey.cpp @@ -0,0 +1,181 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include "CEGraphKey.h" +#include "CEGraphCurve.h" +#include "CEGraphView.h" +#include "CEGraphUI.h" +#include "CETool.h" +#include "CEDragHandlers.h" + +CEGraphKey::CEGraphKey(CEGraphCurve* curve,int index) + :_selected(false),_curve(curve),_index(index),_key(*(curve->animCurve().getFirstKey()+index)),_weighted(curve->animCurve().isWeighted()) +{ +} + +bool CEGraphKey::beginPart(Part part) +{ + glPushName(part); + CEGraphUI* ui = _curve->ui(); + int activeCurve, activeSeg, activePart; + ui->getActivePart(activeCurve, activeSeg, activePart); + bool active = (part == activePart && _index == activeSeg + && _curve->index() == activeCurve); + bool selected = _selected; + ui->setColor(selected ? + (active ? CEGraphUI::HiSelectedColor : + CEGraphUI::SelectedColor) : + (active ? CEGraphUI::HiCurveColor : + CEGraphUI::CurveColor)); + return 1; +} + +void CEGraphKey::endPart() +{ + glPopName(); +} + + +void CEGraphKey::paint(bool selected) +{ + + glPushName(_index); + + CEGraphUI* ui = _curve->ui(); + ui->tool()->isSegmentSelected(_selected, _curve->index(), _index).suppress(); + const CEGraphView& view = ui->getView(); + + // key time and value in screen coordinates + double kt=view.px(_key.getTime()); + double kv=view.py(_key.getValue()); + + // draw time dragger + if(beginPart(KeyTime)){ + glBegin(GL_LINES); + glVertex2i(kt,kv-15); + glVertex2i(kt,kv+15); + glEnd(); + endPart(); + } + // draw node of time/value + if(beginPart(Key)){ + glRecti(kt-3,kv-3,kt+4,kv+4); + endPart(); + } + + // draw the handles +// if(_selected) + paintHandles(); + + glPopName(); +} + + + +void CEGraphKey::paintHandles() +{ + double inWeight=_key.getInWeight(),outWeight=_key.getOutWeight(); + if(!_weighted) inWeight=outWeight=3; + double inAngle=M_PI*_key.getInAngle()/180.,outAngle=M_PI*_key.getOutAngle()/180.; + double time=_key.getTime(),value=_key.getValue(); + paintHandle(0,time,value,-inWeight*cos(inAngle),-inWeight*sin(inAngle),_key.getInTangentType() == animlib::AnimKeyframe::kTangentFixed); + paintHandle(1,time,value,outWeight*cos(outAngle),outWeight*sin(outAngle),_key.getOutTangentType() == animlib::AnimKeyframe::kTangentFixed); +} + +namespace{ + double sqr(double x){return x*x;} +} +void CEGraphKey::paintHandle(int num,double x,double y,double dx,double dy,bool fixedHandle) +{ + const CEGraphView& view = _curve->ui()->getView(); + double x1p=view.pxd(x),y1p=view.pyd(y); + double x2p=view.pxd(x+dx),y2p=view.pyd(y+dy); + double normFactor=1./sqrt(sqr(x2p-x1p)+sqr(y2p-y1p)); // TODO: this is expensive + double normx=(x2p-x1p)*normFactor,normy=(y2p-y1p)*normFactor; + double offx=-normy*4,offy=normx*4; + if(!_weighted){ + x2p=x1p+normx*20;y2p=y1p+normy*20; + } + double backx=.8*x2p+.2*x1p; + double backy=.8*y2p+.2*y1p; + _handleAnchorX[num]=view.vx(x2p)-x; + _handleAnchorY[num]=view.vy(y2p)-y; + + + glPushAttrib(GL_CURRENT_BIT); + if(!fixedHandle) glColor3f(1,1,1); + if(fixedHandle) beginPart(Part(HandleBase+num)); + glBegin(GL_LINES); + glVertex2d(x1p,y1p); + glVertex2d(x2p,y2p); + glEnd(); + + if(fixedHandle) endPart(); + if(fixedHandle) beginPart(Part(KnobBase+num)); + if(fixedHandle) glRecti(int(x2p-2), int(y2p-2), int(x2p+3), int(y2p+3)); + else{ + glBegin(GL_TRIANGLES); + glVertex2d(x2p,y2p); + glVertex2d(backx+offx,backy+offy); + glVertex2d(backx-offx,backy-offy); + glEnd(); + } + if(fixedHandle) endPart(); + glPopAttrib(); +} + +CEGraphKey::~CEGraphKey() +{ +} + +CEDragHandler* CEGraphKey::getDragHandler(int part,int keystate) +{ + bool alt = keystate & Qt::AltModifier; + switch (part) { + case NoPart: + { + return 0; + } + case KeyTime: + { + double hsnap = alt ? 0.0 : 1.0; + return new CEKeyMoveHandler(this, 1, 0, hsnap); + } + case Key: + { + double hsnap = alt ? 0.0 : 1.0; + return new CEKeyMoveHandler(this, alt, 1, hsnap); + } + // new CEBezHandler(key,handle,dragAngle,dragLength) + case HandleBase+0: return new CEBezHandler(this,0,1,0,_weighted); + case HandleBase+1: return new CEBezHandler(this,1,1,0,_weighted); + case KnobBase+0: return new CEBezHandler(this,0,alt,1,_weighted); + case KnobBase+1: return new CEBezHandler(this,1,alt,1,_weighted); + } + return 0; +} + + + + + + + + + + + + diff --git a/src/SeExprEditor/CE/CEGraphKey.h b/src/SeExprEditor/CE/CEGraphKey.h new file mode 100644 index 00000000..6c266d5e --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphKey.h @@ -0,0 +1,65 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef CEGraphKey_h +#define CEGraphKey_h +#include + +class CEGraphCurve; +class CEDragHandler; +class CEGraphKey{ +public: + CEGraphKey(CEGraphCurve* curve,int index); + ~CEGraphKey(); + void paint(bool selected); + + enum Part { + // these are listed in increasing grab priority + NoPart, Seg, HandleBase=100, KnobBase=200, KeyTime=300, Key, + }; + + CEDragHandler* getDragHandler(int part,int keystate); + CEGraphCurve* curve(){return _curve;} + int index(){return _index;} + const animlib::AnimKeyframe& key() const{return _key;} + bool weighted() const{return _weighted;} +private: + bool beginPart(Part part); + void endPart(); + void paintHandles(); + void paintHandle(int num,double x,double y,double dx,double dy,bool fixedHandle); + + bool _selected; + CEGraphCurve* _curve; + int _index; + const animlib::AnimKeyframe _key; + bool _weighted; + double _handleAnchorX[2]; + double _handleAnchorY[2]; +}; + + +#endif + + + + + + + + + + diff --git a/src/SeExprEditor/CE/CEGraphSeg.cpp b/src/SeExprEditor/CE/CEGraphSeg.cpp new file mode 100644 index 00000000..6df7e6b6 --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphSeg.cpp @@ -0,0 +1,378 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include +#include +#include "CETool.h" +#include "CEGraphUI.h" +#include "CEDragHandlers.h" +#include "CEGraphCurve.h" +#include "CEGraphSeg.h" + + +static double HandleMin = 20; + + + +CEGraphSeg::CEGraphSeg(CEGraphCurve* curve,int index) + : _viewValid(0), _curve(curve), _index(index), _unbounded(0), + _numParams(0), _params(0), + _keytime(0), _keyval(0), _outtime(0), _outval(0), _nextval(0), + _selected(0), _pendingSel(0) +{ + auto it=curve->animCurve().getFirstKey()+index; + _keytime=it->getTime(); + _keyval=it->getValue(); + if(indexanimCurve().getNumKeys())-1){ + auto itnext=curve->animCurve().getFirstKey()+index+1; + _outval=itnext->getValue(); + _outtime=itnext->getTime(); + }else{ + _unbounded=true; + + _outval=_keyval; + _outtime=_keytime; + } + +// std::cerr<<"we have "<<_keytime<<" "<<_keyval<<" out "<<_outtime<<" "<<_outval<<" tang "<getInTangentType())<<" outang "<getOutAngle()<ui(); + if (!selected) { + // determine if we're selected on the first (non-selection) pass + _selected = 0; + } + + const CEGraphView& view = ui->getView(); + + // paint seg + glPushName(_index); + + if(_selected == selected){ + if (beginPart(Seg)) { + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + paintSeg(); // defined in subclasses + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); + + // paint discontinuity between segs (if present) + if (!_unbounded && _outval != _nextval) { + glEnable(GL_LINE_STIPPLE); + glLineStipple(2, 0x5555); + glBegin(GL_LINES); + int ot = view.px(_outtime); + glVertex2i(ot, view.py(_outval)); + glVertex2i(ot, view.py(_nextval)); + glEnd(); + glDisable(GL_LINE_STIPPLE); + } + endPart(); + } + } + + glPopName(); + +} + + +bool +CEGraphSeg::beginPart(Part part) +{ + glPushName(part); + CEGraphUI* ui = _curve->ui(); + int activeCurve, activeSeg, activePart; + ui->getActivePart(activeCurve, activeSeg, activePart); + bool active = (part == activePart && _index == activeSeg + && _curve->index() == activeCurve); + bool selected = _selected || (part == Key && _pendingSel); + ui->setColor(selected ? + (active ? CEGraphUI::HiSelectedColor : + CEGraphUI::SelectedColor) : + (active ? CEGraphUI::HiCurveColor : + CEGraphUI::CurveColor)); + return 1; +} + + +void +CEGraphSeg::endPart() +{ + glPopName(); +} + + +void +CEGraphSeg::paintKey() +{ + const CEGraphView& view = _curve->ui()->getView(); + + int kt = view.px(_keytime); + int kv = view.py(_keyval); + + // draw line for dragging time + if (beginPart(KeyTime)) { + glBegin(GL_LINES); + glVertex2i(kt, kv-15); + glVertex2i(kt, kv+16); + glEnd(); + endPart(); + } + // draw key rectangle + if (beginPart(Key)) { + glRecti(kt-3, kv-3, kt+4, kv+4); + endPart(); + } +} + + +CEDragHandler* +CEGraphSeg::getDragHandler(int part, int keystate) +{ + bool alt = keystate & Qt::AltModifier; + switch (part) { + case Seg: + { + return alt ? new CENewKeyHandler(this) : 0; + } + } + return 0; +} + + +void +CEGraphSeg::paintHandle(int num, double x, double y, double dx, double dy, + double zx, double zy, bool joinKnob) +{ + const CEGraphView& view = _curve->ui()->getView(); + + // draw handle + double x1p = view.pxd(x), y1p = view.pyd(y); + double x2p = view.pxd(x+dx), y2p = view.pyd(y+dy); + beginPart(Part(HandleBase + num)); + glBegin(GL_LINES); + glVertex2d(x1p, y1p); + glVertex2d(x2p, y2p); + glEnd(); + + // draw handle extender (if needed) + double x3p=x2p, y3p=y2p; + bool extend = 0; + + if (dx == 0 && dy == 0) { + // handle length is 0, use zx, zy to determine extend direction + double scale = HandleMin / sqrt(zx*zx + zy*zy); + x3p = x1p + zx * scale; + y3p = y1p + zy * scale; + extend = 1; + } else { + // find handle length + double dxp = x2p-x1p; + double dyp = y2p-y1p; + double len = sqrt(dxp*dxp + dyp*dyp); + if (len < HandleMin) { + // scale handle up to minimum length + double scale = HandleMin / len; + x3p = x1p + dxp * scale; + y3p = y1p + dyp * scale; + extend = 1; + } + } + + if (extend) { + glEnable(GL_LINE_STIPPLE); + glLineStipple(2, 0x5555); + glBegin(GL_LINES); + glVertex2d(x2p, y2p); + glVertex2d(x3p, y3p); + glEnd(); + glDisable(GL_LINE_STIPPLE); + } + + if (!joinKnob) { + endPart(); + beginPart(Part(KnobBase + num)); + } + + // draw knob + glRecti(int(x3p-2), int(y3p-2), int(x3p+3), int(y3p+3)); + endPart(); +} + + +CEGraphUniformSeg::CEGraphUniformSeg(CEGraphCurve* curve,int index) + : CEGraphSeg(curve,index), _samples(0) +{ +} + + +CEGraphUniformSeg::~CEGraphUniformSeg() +{ + delete [] _samples; +} + + +void +CEGraphUniformSeg::paintSeg() +{ + if (!_viewValid) updateView(); + const CEGraphView& view = _curve->ui()->getView(); + if(_numSamples==0) return; + glPushAttrib(GL_CURRENT_BIT|GL_LINE_BIT); + glLineWidth(2.); + GLfloat color[4]; + glGetFloatv(GL_CURRENT_COLOR, &color[0]); + + if(_unbounded || firstSeg()) glColor3f(.6f,.6f,.6f); + bool transitionedToRealSegment=false; + // draw curve samples + int sample=0; + if(firstSeg()){ + glBegin(GL_LINE_STRIP); + while(sample<_numSamples){ + float x=_sampleStart + _sampleSpacing * sample; + glVertex2d(view.pxd(x), + view.pyd(_samples[sample])); + sample++; + if(x>=_keytime) break; + } + glEnd(); + glColor3fv(&color[0]); + } + + glBegin(GL_LINE_STRIP); + glVertex2d(view.pxd(_keytime), view.pyd(_keyval)); + for (; sample < _numSamples; sample++){ + float x=_sampleStart + _sampleSpacing * sample; + glVertex2d(view.pxd(x), + view.pyd(_samples[sample])); + } + if (!_unbounded) glVertex2d(view.pxd(_outtime), view.pyd(_outval)); + glEnd(); + glPopAttrib(); + +} + + +void +CEGraphUniformSeg::updateView() +{ + // need to update samples based on view + if (_samples) { + // free previous samples + delete [] _samples; + _samples = 0; + } + + // determine view range + const CEGraphView& view = _curve->ui()->getView(); + double l = view.left(); + double r = view.right(); + + // aim for a sample every n pixels + double s = view.pixelWidth()*2; + // increase to an even power of 2 for smooth zooms + _sampleSpacing = s;//pow(2,ceil(log(s)*(1/M_LN2))); + + // find the leftmost sample + int start = int(floor(l/_sampleSpacing)); + if (!firstSeg()) { + double keysamp = _keytime/_sampleSpacing; + if (start < keysamp) start = int(floor(keysamp)+1); + } + _sampleStart = start * _sampleSpacing; + + // find the rightmost sample + int end = int(ceil(r/_sampleSpacing)); + if (!_unbounded) { + double keysamp = _outtime/_sampleSpacing; + if (end > keysamp) end = int(ceil(keysamp)-1); + } + _sampleEnd = end * _sampleSpacing; + + // compute the number of samples + _numSamples = end-start+1; + if (_numSamples <= 0) { + _numSamples = 0; + }else { + // sample the curve + std::vector samples; + double dx=(_sampleEnd-_sampleStart)/(_numSamples); + double x=_sampleStart; + for(int i=0;i<_numSamples;i++){ + x+=dx; + samples.push_back(x); + } + std::vector vals=_curve->animCurve().getValues(samples); + + _samples = new double[_numSamples]; + for (int i = 0; i < _numSamples; i++){ + _samples[i] = vals[i]; + //std::cerr<<"eval at "<"<animCurve().getFirstKey()+index; + double thetaIn=M_PI/180.*it->getOutAngle(); + double thetaOut=0; + double weightIn=it->getOutWeight(); + double weightOut=1; + + if(index < int(curve->animCurve().getNumKeys())-1){ + thetaOut=M_PI/180.*(it+1)->getInAngle(); + weightOut=(it+1)->getInWeight(); + } + + _params[0] = weightIn*cos(thetaIn); + _params[1] = weightIn*sin(thetaIn); + _params[2] = weightOut*cos(thetaOut); + _params[3] = weightOut*sin(thetaOut); +} + + +void CEGraphBezSeg::paintHandles() +{} + + +CEDragHandler* +CEGraphBezSeg::getSegmentHandler(int part, int keystate) +{ + return NULL; +} diff --git a/src/SeExprEditor/CE/CEGraphSeg.h b/src/SeExprEditor/CE/CEGraphSeg.h new file mode 100644 index 00000000..856f5e13 --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphSeg.h @@ -0,0 +1,125 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef CEGraphSeg_h +#define CEGraphSeg_h + +#include + +class CEGraphCurve; +class CEDragHandler; + +class CEGraphSeg +{ +public: +#if 0 + struct InitData { + InitData(CEGraphCurve* c, int n) : curve(c), index(n) {} + CEGraphCurve* curve; + int index; + }; +#endif + CEGraphSeg(CEGraphCurve* curve,int index); + virtual ~CEGraphSeg(); + CEGraphCurve* curve() { return _curve; } + int index() { return _index; } + bool firstSeg() { return _index==0; } + bool unbounded() { return _unbounded; } + const char* type() { return _type.c_str(); } + int numParams() { return _numParams; } + double param(int n) { return n < 0 || n >= _numParams ? 0 : _params[n]; } + double keyTime() { return _keytime; } + double keyValue() { return _keyval; } + double outTime() { return _outtime; } + double outValue() { return _outval; } + + enum Part { + // these are listed in increasing grab priority + NoPart, Seg, HandleBase=100, KnobBase=200, KeyTime=300, Key, + }; + void invalidateView() { _viewValid = 0; } + + void paint(bool selected); + CEDragHandler* getDragHandler(int part, int keystate); + virtual CEDragHandler* getSegmentHandler(int part, int keystate) + { return 0; } + void setPendingSel(bool pendingSel) { _pendingSel = pendingSel; } + bool isPendingSel() { return _pendingSel; } + +protected: + bool beginPart(Part part); + void endPart(); + virtual void paintSeg()=0; + virtual void paintHandles() {} + void paintHandle(int num, double x, double y, double dx, double dy, + double zx, double zy, bool joinKnob=1); + + bool _viewValid; + + void paintKey(); + + CEGraphCurve* _curve; // parent curve + int _index; // index of segment in curve + bool _unbounded; // true if seg extends to +infinity + std::string _type; // segment interpolationtype + int _numParams; // number of segment params + double *_params; // segment params + + // key data (not valid for first seg) + double _keytime; // time of key starting this seg + double _keyval; // value of this seg at key time + // out data (not valid for last seg) + double _outtime; // time of next key + double _outval; // value of this seg at out time + double _nextval; // value of next seg at out time + + bool _selected; // only valid during a paint + bool _pendingSel; // true if being marquee selected +}; + + +// Handles uniform sampling - provides no drag handles +class CEGraphUniformSeg : public CEGraphSeg +{ +public: + CEGraphUniformSeg(CEGraphCurve* curve,int index); + ~CEGraphUniformSeg(); + +protected: + virtual void paintSeg(); + +private: + void updateView(); + + // sample data + double _sampleStart; + double _sampleEnd; + double _sampleSpacing; + int _numSamples; + double* _samples; +}; + +class CEGraphBezSeg : public CEGraphUniformSeg +{ +public: + CEGraphBezSeg(CEGraphCurve* curve,int index); +protected: + virtual void paintHandles(); + virtual CEDragHandler* getSegmentHandler(int part, int keystate); +}; + + +#endif diff --git a/src/SeExprEditor/CE/CEGraphUI.cpp b/src/SeExprEditor/CE/CEGraphUI.cpp new file mode 100644 index 00000000..c7e65cf8 --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphUI.cpp @@ -0,0 +1,1104 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CEGraphUI.cpp +* @brief Contains the Definition of class CEGraphUI. +* +* 09/18/06 - rsharma Changed setRawName to fromString for xft +*/ + +#include "CEGraphUI.h" +#include +#include +#include +#include +#include +#include "CETool.h" +#include "CEGraphCurve.h" +#include "CEGraphKey.h" +#include "CEGraphSeg.h" +#include "CEDragHandlers.h" + +#include +using namespace std; + +#include +#include + +// #include conflicts w/ Qt! Just declare what we need. +extern "C" void glXUseXFont(Qt::HANDLE, int, int, int); + + +static double RaiseToInc(double val, double inc) +{ + return ceil(val/inc)*inc; +} + + +static double LowerToInc(double val, double inc) +{ + return floor(val/inc)*inc; +} + + +/** + * Constructor. + */ +CEGraphUI::CEGraphUI(QWidget* parent, CETool* tool) + : QGLWidget(QGLFormat(QGL::DoubleBuffer|QGL::DepthBuffer|QGL::HasOverlay), + parent), + _tool(tool), + //_ce(tool->rcvrId()), + _fontListBase(0), + _fontListCount(0), + _viewValid(0), + _showCrossHairs(0), + _crossX(0), _crossY(0), + _showSelBox(0), + _selBoxX1(0), _selBoxY1(0), _selBoxX2(0), _selBoxY2(0), + _curveListValid(0), + _activeCurve(-1), + _activeSeg(-1), + _activePart(-1), + _dragHandler(0) +{ + setObjectName("Graph"); + + setMouseTracking(1); + + QFontMetrics fm(_font); + _scalesWidth = fm.width("-99999")+15; + _scalesHeight = fm.ascent()+12; + + // wire-up the notifications + connect(_tool, SIGNAL(curveChanged(int)), SLOT(invalidateCurve(int))); + connect(_tool, SIGNAL(curveListChanged()), SLOT(invalidateCurveList())); + connect(_tool, SIGNAL(selectionChanged()), SLOT(invalidateSelection())); + connect(_tool, SIGNAL(viewChanged()), SLOT(invalidateView())); + connect(_tool, SIGNAL(timeModeChanged()), SLOT(invalidateTimeMode())); + + // init the colors + _colors[BgColor].setRgb(48,48,48); + _colors[ScaleBgColor].setRgb(128,128,128); + _colors[ScaleColor].setRgb(0,0,0); + _colors[GridColor].setRgb(80,80,80); + _colors[TimebarColor].setRgb(192,192,255); + _colors[OverlayColor].setRgb(192,192,200); + _colors[SelectedColor].setRgb(204,204,38); + _colors[HiSelectedColor] = _colors[SelectedColor].light(); + _colors[CurveColor].setRgb(200,105,50); + _colors[HiCurveColor].setRgb(200,135,50); // = _colors[CurveColor].light(); +} + +/** + * Destructor. + */ +CEGraphUI::~CEGraphUI() +{ + clearCurves(); +} + +/* +void +CEGraphUI::show() +{ + QGLWidget::show(); + invalidateView(); + updateGL(); + resize(width()-1, height()-1); +} +*/ + +void +CEGraphUI::setColor(ColorType color) +{ + qglColor(_colors[color]); +} + + +const QColor& +CEGraphUI::getColor(ColorType color) +{ + return _colors[color]; +} + + +void +CEGraphUI::clearCurves() +{ + for (size_t i = 0; i < _curves.size(); i++) { + delete _curves[i]; + } + _curves.clear(); +} + + +CEGraphCurve* +CEGraphUI::getCurve(int curve) +{ + if (!_curveListValid) updateCurves(); + if (curve < 0 || curve >= (int) _curves.size()) return 0; + return _curves[curve]; +} + + +CEGraphSeg* +CEGraphUI::getSeg(int curve, int seg) +{ + if (!_curveListValid) updateCurves(); + if (curve < 0 || curve >= (int) _curves.size()) return 0; + CEGraphKey* keyPtr=0; + CEGraphSeg* segPtr=0; + _curves[curve]->getSegAndKey(seg,segPtr,keyPtr); + return segPtr; +} + +CEGraphKey* +CEGraphUI::getKey(int curve, int seg) +{ + if (!_curveListValid) updateCurves(); + if (curve < 0 || curve >= (int) _curves.size()) return 0; + CEGraphKey* keyPtr=0; + CEGraphSeg* segPtr=0; + _curves[curve]->getSegAndKey(seg,segPtr,keyPtr); + return keyPtr; +} + + +const CEGraphView& +CEGraphUI::getView() +{ + if (!_viewValid) updateView(); + return _view; +} + + +int +CEGraphUI::doSelectModeRender(int x1, int x2, int y1, int y2, + GLuint* buffer, int bufsize) +{ + makeCurrent(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + if (x1 == x2) x2++; + if (y1 == y2) y2++; + + glOrtho(x1, x2, y1, y2, -1, 1); + glSelectBuffer(bufsize, buffer); + glRenderMode(GL_SELECT); + glInitNames(); + paintCurves(); + int numHits = glRenderMode(GL_RENDER); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + return numHits; +} + + +void CEGraphUI::initializeGL() +{ + QGLWidget::initializeGL(); +} + + +void CEGraphUI::resizeGL(int w, int h) +{ + glViewport(0, 0, w, h ); + // set GL projection matrix to map GL units to pixels + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, w, 0, h, -1, 1); +#ifdef linux + glTranslated(0.25, 0.25, 0); +#endif + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +void CEGraphUI::resizeOverlayGL(int w, int h) +{ + // we use the same coordinate system in the overlay + resizeGL(w, h); +} + + +void CEGraphUI::paintGL() +{ + qglClearColor(_colors[BgColor]); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (!_viewValid) + { + updateView(); + } + if (!_curveListValid) + { + updateCurves(); + } + paintScales(); + paintCurves(); +} + + +void CEGraphUI::paintOverlayGL() +{ + qglClearColor(overlayContext()->overlayTransparentColor()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + paintOverlay(); +} + + +void CEGraphUI::getNextIncrement(double min, int timeMode, + double& inc, int& decimals) +{ + decimals = 0; + if (min >= 1 && timeMode > 0) { + // integer case - increments depend on mode + if (timeMode == 1) { + // feet-frames mode + if (min <= 16.001) { + // sub-foot + if (min > 8) inc = 16; + else if (min > 4) inc = 8; + else if (min > 2) inc = 4; + else if (min > 1) inc = 2; + else inc = 1; + return; + } + // multiples of feet + getNextIncrement(min/16, 0, inc, decimals); + inc *= 16; + return; + + } else if (timeMode == 2) { + // seconds-frames mode + if (min <= 24.001) { + if (min > 12) inc = 24; + else if (min > 8) inc = 12; + else if (min > 4) inc = 8; + else if (min > 2) inc = 4; + else if (min > 1) inc = 2; + else inc = 1; + return; + } + // multiples of seconds + getNextIncrement(min/24, 0, inc, decimals); + inc *= 24; + return; + } + } + // default case, use 1's and 5's + double temp = floor(log10(min)); + if (min < 1) decimals = int(-temp); + inc = pow(10, temp); // 1's + if (inc >= min) return; + inc *= 2; // 2's + if (inc >= min) return; + inc *= 2.5; // 5's + if (inc >= min) return; + inc *= 2; // 10's + if (decimals > 0) decimals--; +} + + + +void CEGraphUI::getNextTickIncrement(double inc, + int timeMode, + double& tickInc) +{ + if (inc >= 2 && timeMode > 0) { + if (timeMode == 1) { + // feet-frames mode + if (inc <= 16.001) { + // sub-foot + if (inc > 8) tickInc = 4; + else if (inc > 4) tickInc = 2; + else tickInc = 1; + return; + } + // next power of 10 (in feet) below inc + tickInc = pow(10, ceil(log10(inc*(.1/16))))*16; + return; + + } else if (timeMode == 2) { + // seconds-frames mode + if (inc <= 24.001) { + // sub-second + if (inc > 12) tickInc = 8; + else if (inc > 8) tickInc = 4; + else if (inc > 4) tickInc = 2; + else tickInc = 1; + return; + } + // next power of 10 (in frames) below inc + tickInc = pow(10, ceil(log10(inc*(.1/24))))*24; + return; + } + } + // default: tickInc should always be the next power of 10 below inc + tickInc = pow(10, ceil(log10(inc*.1))); +} + + +void CEGraphUI::paintScales() +{ + // some handy values + int w = width(); + int h = height(); + int sw = _scalesWidth; + int sh = _scalesHeight; + + double l = _view.left(); + double r = _view.right(); + double b = _view.bottom(); + double t = _view.top(); + + int timeMode; + _tool->getTimeMode(timeMode); + + // compute increments from view and window sizes + double gridIncX, gridIncY, tickIncX, tickIncY; + int gridDecimalsX, gridDecimalsY; + getNextIncrement(60.0/w*_view.vw(), timeMode, gridIncX, gridDecimalsX); + getNextIncrement(60.0/h*_view.vh(), 0, gridIncY, gridDecimalsY); + getNextTickIncrement(gridIncX, timeMode, tickIncX); + getNextTickIncrement(gridIncY, 0, tickIncY); + + // clear scales to scale bg color + glEnable(GL_SCISSOR_TEST); + qglClearColor(_colors[ScaleBgColor]); + glScissor(0, 0, w, sh-1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glScissor(0, 0, sw-1, h); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); + + // draw time-display mode button + QFontMetrics fm(_font); + setColor(ScaleColor); + const char* modeText; + switch (timeMode) { + case 0: modeText = "f"; break; + case 1: modeText = "f-f"; break; + case 2: modeText = "s:f"; break; + default: modeText = "?"; break; + } + + // draw box around time mode to indicate button + { + int tw = fm.width(modeText); + int th = fm.ascent(); + printStringAt(17-tw/2, 4, modeText); + glBegin(GL_LINE_LOOP); + glVertex2i(2, 1); + glVertex2i(2, th+3); + glVertex2i(32, th+3); + glVertex2i(32, 1); + glEnd(); + } + + // draw time scale + double x, y; + setColor(ScaleColor); + glBegin(GL_LINES); + if (tickIncX) { + int tickBottom = sh-7; + int tickTop = sh-1; + for (x = RaiseToInc(l,tickIncX); x <= r; x += tickIncX) { + int px = _view.px(x); + glVertex2i(px, tickBottom); + glVertex2i(px, tickTop); + } + } + + int gridBottom = sh-12; + int gridTop = sh-1; + for (x = RaiseToInc(l,gridIncX); x <= r; x += gridIncX) { + int px = _view.px(x); + glVertex2i(px, gridBottom); + glVertex2i(px, gridTop); + } + glEnd(); + + for (x = RaiseToInc(l,gridIncX); x <= r; x += gridIncX) { + char prefix[20]; + double frames; + switch (timeMode) { + case 1: // feet-frames + { + int feet = int(floor(x/16)); + frames = x-feet*16; + sprintf(prefix, "%d-", feet); + } + break; + case 2: // seconds-frames + { + int seconds = int(floor(x/24)); + frames = x-seconds*24; + sprintf(prefix, "%d:", seconds); + } + break; + default: + frames = x; + prefix[0] = '\0'; + break; + } + + char buff[40]; + if (gridDecimalsX) + sprintf(buff, "%s%.*f", prefix, gridDecimalsX, frames); + else + sprintf(buff, "%s%d", prefix, int(frames)); + + printStringAt(_view.px(x)-fm.width(buff)/2, 4, buff); + } + + // draw value scale + glBegin(GL_LINES); + if (tickIncY) { + int tickLeft = sw-7; + int tickRight = sw-1; + for (y = RaiseToInc(b,tickIncY); y <= t; y += tickIncY) { + int py = _view.py(y); + glVertex2i(tickLeft, py); + glVertex2i(tickRight, py); + } + } + int gridLeft = sw-12; + int gridRight = sw-1; + for (y = RaiseToInc(b,gridIncY); y <= t; y += gridIncY) { + int py = _view.py(y); + glVertex2i(gridLeft, py); + glVertex2i(gridRight, py); + } + glEnd(); + int textOffsetY = fm.ascent()/2-3; + for (y = RaiseToInc(b,gridIncY); y <= t; y += gridIncY) { + char buff[20]; + if (gridDecimalsY) + sprintf(buff, "%.*f", gridDecimalsY, y); + else + sprintf(buff, "%d", int(y)); + int left = (_scalesWidth-fm.width(buff)-7)/2; + if (left < 0) left = 0; + printStringAt(left, _view.py(y)-textOffsetY, buff); + } + + // clear main area to bg color + glEnable(GL_SCISSOR_TEST); + qglClearColor(_colors[BgColor]); + glScissor(sw, sh, w-sw, h-sh); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // draw grid lines + //glEnable(GL_LINE_STIPPLE); + //glLineStipple(4, 0x5555); + setColor(GridColor); + // (start on multiple of 16 pixels to stabilize stipple) + int gb = _view.py(LowerToInc(b, 16*_view.pixelHeight())); + int gt = _view.py(t); + for (x = RaiseToInc(l,gridIncX); x <= r; x += gridIncX) { + int px = _view.px(x); + glBegin(GL_LINES); + glVertex2i(px, gb); + glVertex2i(px, gt); + glEnd(); + } + + int gl = _view.px(LowerToInc(l, 16*_view.pixelWidth())); + int gr = _view.px(r); + for (y = RaiseToInc(b,gridIncY); y <= t; y += gridIncY) { + int py = _view.py(y); + glBegin(GL_LINES); + glVertex2i(gl, py); + glVertex2i(gr, py); + glEnd(); + } + // glDisable(GL_LINE_STIPPLE); + glDisable(GL_SCISSOR_TEST); + + // draw border between scales and main area + setColor(ScaleColor); + glBegin(GL_LINE_STRIP); + glVertex2i(sw-1, h); + glVertex2i(sw-1, sh-1); + glVertex2i(w, sh-1); + glEnd(); +} + + + +void +CEGraphUI::paintCurves() +{ + int w = width(); + int h = height(); + int sw = _scalesWidth; + int sh = _scalesHeight; + + // grab the current GL context. + makeCurrent(); + + glEnable(GL_SCISSOR_TEST); + glScissor(sw, sh, w-sw, h-sh); + + // paint curves w/ selected segs last to put them on top + for (int selected = 0; selected <= 1; selected++) + for (int i = _curves.size()-1; i >= 0; i--) + _curves[i]->paint(selected); + glDisable(GL_SCISSOR_TEST); +} + + +void CEGraphUI::paintOverlay(bool erase) +{ + if (!overlayContext()) return; + // erase the overlay by re-drawing as transparent to reduce flicker + qglColor(erase ? overlayContext()->overlayTransparentColor() : + _colors[OverlayColor]); + if (_showCrossHairs) + paintCrossHairs(); + if (_showSelBox) + paintSelBox(); + // paintTimeBar(); +} + + +void CEGraphUI::paintCrossHairs() +{ + int x = _crossX; + int y = _crossY; + bool drawX = x >= _scalesWidth; + bool drawY = y >= _scalesHeight; + if (!drawX || !drawY) return; + + glBegin(GL_LINES); + if (drawX) { + glVertex2i(x, _scalesHeight); + glVertex2i(x, _scalesHeight+10); + } + if (drawY) { + glVertex2i(_scalesWidth, y); + glVertex2i(_scalesWidth+10, y); + } + glEnd(); +} + + +void CEGraphUI::moveCrossHairs(int x, int y) +{ + makeOverlayCurrent(); + if (!_showCrossHairs) + _showCrossHairs = 1; + else + paintOverlay(true); // true => erase? yes. + _crossX = x; + _crossY = y; + paintOverlay(); + + makeCurrent(); + glFlush(); +} + + +void CEGraphUI::hideCrossHairs() +{ + if (!_showCrossHairs) return; + makeOverlayCurrent(); + paintOverlay(true); // true => erase? yes. + _showCrossHairs = 0; + paintOverlay(); + + makeCurrent(); + glFlush(); +} + + +void CEGraphUI::pickActive(int x, int y) +{ + static const int bufsize = 1000; + GLuint selbuff[bufsize]; + int numHits = doSelectModeRender(x-4, x+5, y-4, y+5, selbuff, bufsize); + + // Look for highest priority object. In the case of a tie, we prefer + // the one that is selected. If there's still a tie, then we pick the + // last one rendered (which is the one on top). + int activeCurve = -1; + int activeSeg = -1; + int activePart = -1; + bool activeSelected = 0; + GLuint *p = selbuff; + + while (numHits--) { + GLuint numNames = *p++; + *p++; // GLuint zmin = + *p++; // GLuint zmax = + if (numNames >= 3) + { + int curve = p[0]; + int seg = p[1]; + int part = p[2]; + bool selected = 0; + _tool->isSegmentSelected(selected, curve, seg).suppress(); + + if (part > activePart || + (part == activePart && + (selected || !activeSelected))) + { + activeCurve = curve; + activeSeg = seg; + activePart = part; + activeSelected = selected; + } + } + p += numNames; + } + + if (activeCurve != _activeCurve || + activeSeg != _activeSeg || + activePart != _activePart) + { + _activeCurve = activeCurve; + _activeSeg = activeSeg; + _activePart = activePart; + update(); + } +} + +void CEGraphUI::paintSelBox() +{ + int x1 = _selBoxX1; + int y1 = _selBoxY1; + int x2 = _selBoxX2; + int y2 = _selBoxY2; + + glEnable(GL_SCISSOR_TEST); + glScissor(_scalesWidth, _scalesHeight, + width()-_scalesWidth, height()-_scalesHeight); + + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, 0x5555); + + glBegin(GL_LINE_STRIP); + glVertex2i(x1,y1); + glVertex2i(x2,y1); + glVertex2i(x2,y2); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2i(x1,y1); + glVertex2i(x1,y2); + glVertex2i(x2,y2); + glEnd(); + + glDisable(GL_LINE_STIPPLE); + glDisable(GL_SCISSOR_TEST); +} + + +void CEGraphUI::moveSelBox(int x1, int y1, int x2, int y2) +{ + makeOverlayCurrent(); + if (!_showSelBox) + _showSelBox = 1; + else + paintOverlay(true); // true => erase? yes. + + _selBoxX1 = x1; + _selBoxY1 = y1; + _selBoxX2 = x2; + _selBoxY2 = y2; + paintOverlay(); + + makeCurrent(); + glFlush(); +} + + +void CEGraphUI::hideSelBox() +{ + if (!_showSelBox) return; + makeOverlayCurrent(); + paintOverlay(true); // true => erase? yes. + _showSelBox = 0; + paintOverlay(); + + makeCurrent(); + glFlush(); +} + + + +void CEGraphUI::paintTimeBar(double frame) +{ +#if 0 + setViewXForm(getView(),1,0); + glBegin(GL_LINES); + glVertex2i(frame, _scalesHeight); + glVertex2i(frame, height()); + glEnd(); +#endif +} + + +void CEGraphUI::printStringAt(double x, double y, const char* str) +{ + // check for legal chars in string + for (const char* cp = str; *cp; cp++) { + if (*cp < ' ' || ((unsigned char)*cp) >= 128) { + // got an illegal char - bail out for now + std::cerr << "Illegal char in GL string - skipping: " << str + << std::endl; + return; + } + } + + glEnable(GL_DEPTH_TEST); + renderText(x, y, 0.1, str, _font); + glDisable(GL_DEPTH_TEST); +} + +void CEGraphUI::resizeEvent(QResizeEvent *e) +{ + invalidateView(); + QGLWidget::resizeEvent(e); +} + +void CEGraphUI::keyPressEvent(QKeyEvent *event) +{ + if(event->key()==Qt::Key_Backspace || event->key()==Qt::Key_Delete){ + _tool->deleteSegments(); + } +} + +void CEGraphUI::mousePressEvent(QMouseEvent* e) +{ + setFocus(); + // ignore button press if a drag is already active + if (_dragHandler) return; + + int x = e->pos().x(); + int y = height() - e->pos().y(); + + // select a drag handler + if (e->button() == Qt::LeftButton) + { + if (_activeCurve >= 0 && _activeSeg >= 0) + { + if(auto key = getKey(_activeCurve, _activeSeg)) + { + // first, select segment (or add/toggle based on modifiers) + bool selected = 0; + _tool->isSegmentSelected(selected, _activeCurve, + _activeSeg); + int keystate = e->modifiers() & (Qt::ShiftModifier | + Qt::ControlModifier | + Qt::AltModifier | + Qt::MetaModifier); + if (keystate == Qt::ShiftModifier) + { + // add segment to selection + if (!selected) + _tool->selectAddSegment(_activeCurve, _activeSeg); + } + else if (keystate == Qt::ControlModifier) + { + // toggle segment selection + if (selected) + _tool->deselectSegment(_activeCurve, _activeSeg); + else + _tool->selectAddSegment(_activeCurve, _activeSeg); + } + else + { + // select segment + int curve=-1, seg=-1; + _tool->getSelectedSegment(curve, seg).suppress(); + if (curve != _activeCurve || seg != _activeSeg) + _tool->selectSegment(_activeCurve, _activeSeg); + } + // chose a handler for the seg + //_dragHandler =0; // seg->getDragHandler(_activePart, keystate); + _dragHandler = key->getDragHandler(_activePart,keystate); + if(!_dragHandler){ + if(auto seg = getSeg(_activeCurve,_activeSeg)){ + _dragHandler = seg->getDragHandler(_activePart,keystate); + } + } + } + } + else + { + int keystate = e->modifiers() & (Qt::ShiftModifier | + Qt::ControlModifier | + Qt::AltModifier | + Qt::MetaModifier); + bool append = keystate == Qt::ShiftModifier; + bool toggle = keystate == Qt::ControlModifier; + bool addKey = keystate == Qt::AltModifier; + if(addKey){ + // special case no keys in curve and you still want to add one + int curve; + if(_tool->getSelectedCurve(curve)==errSUCCESS){ + double _anchorTime = _view.vx(x); + double _anchorValue = _view.vy(y); + int loc=_tool->insertKey(_anchorTime); + _tool->setSegment(curve,loc,_anchorTime,_anchorValue,0.,0.,1.,1., + animlib::AnimKeyframe::kTangentAuto,animlib::AnimKeyframe::kTangentAuto); + } + + }else{ + if (!append && !toggle) + _tool->clearSelection(); + _dragHandler = new CESelBoxHandler(toggle); + + } + } + } + else if (e->button() == Qt::MidButton) + { + // pan/zoom + switch (e->modifiers()) + { + case 0: + _dragHandler = new CEPanHandler; + break; + case Qt::ControlModifier: + { + bool zoomX = 1; // TODO: zoomX = 0 if over y scale + bool zoomY = 1; // TODO: zoomY = 0 if over x scale + _dragHandler = new CEZoomHandler(zoomX, zoomY); + } + break; + default: break; + } + } + + if (_dragHandler) + { + // hide crosshairs if suppressed by handler + if (!_dragHandler->showCrossHairs()) + hideCrossHairs(); + + msg::list selections; + std::vector graph_keys; + int num_segments = 0; + _tool->getSelection(selections); + + for (int i=0; i < selections.size(); i+=2) + { + //Values are in pairs. Curve/list of points + int my_curve = selections[i].asint(); + msg::list my_segments = selections[i+1]; + for (int j=0; j 0 ) + { + _dragHandler->setMultiDrag(graph_keys); + } + + _dragHandler->setAnchor(this, x, y); + + // invoke handler + _dragHandler->mouseDown(); + } +} + + +void CEGraphUI::mouseDoubleClickEvent(QMouseEvent* e) +{ + int x = e->pos().x(); + int y = height() - e->pos().y(); + + if (e->button() == Qt::LeftButton) { + if (_activeCurve >= 0) { + int keystate = e->modifiers() & (Qt::ShiftModifier | + Qt::ControlModifier | + Qt::AltModifier | + Qt::MetaModifier); + if (keystate == Qt::ShiftModifier) { + // add curve to selection + _tool->selectAddCurve(_activeCurve); + } + else if (keystate == Qt::ControlModifier) { + // do nothing - control just toggles segments + } + else { + // select curve + _tool->selectCurve(_activeCurve); + // add key + int curve; + if (_tool->getSelectedCurve(curve)==errSUCCESS) { + double _anchorTime = _view.vx(x); + double _anchorValue = _view.vy(y); + int loc=_tool->insertKey(_anchorTime); + _tool->setSegment(curve,loc,_anchorTime,_anchorValue,0.,0.,1.,1., + animlib::AnimKeyframe::kTangentAuto,animlib::AnimKeyframe::kTangentAuto); + } + } + } + } +} + + +void CEGraphUI::mouseMoveEvent(QMouseEvent* e) +{ + int x = e->pos().x(); + int y = height() - e->pos().y(); + + // show cross hairs unless suppressed by handler + if (!_dragHandler || _dragHandler->showCrossHairs()) { + moveCrossHairs(x, y); + } + + if (!_dragHandler) { + pickActive(x, y); + } else { + // update drag data + _dragHandler->movePoint(x, y); + + // invoke handler + _dragHandler->mouseMove(); + } +} + + +void CEGraphUI::mouseReleaseEvent(QMouseEvent* e) +{ + // nothing to do if we have no handler + if (!_dragHandler) return; + + // ignore button release until all buttons are released + // bsilva: NO! when the mouse button is up, we are done dragging. +// if ((e->modifiers() & (Qt::ShiftModifier | +// Qt::ControlModifier | +// Qt::AltModifier | +// Qt::MetaModifier)) != Qt::NoModifier) return; + + // invoke handler + _dragHandler->mouseUp(); + + // drag finished + delete _dragHandler; + _dragHandler = 0; + + // show cross-hairs again + int x = e->pos().x(); + int y = height() - e->pos().y(); + moveCrossHairs(x, y); +} + + + +void CEGraphUI::enterEvent(QEvent* e) +{ +} + + +void CEGraphUI::leaveEvent(QEvent* e) +{ + hideCrossHairs(); +} + + +void +CEGraphUI::invalidateCurve(int index) +{ + if (index >= 0 && index < (int) _curves.size()) { + _curves[index]->invalidate(); + update(); // schedule repaint + } +} + + +void +CEGraphUI::invalidateCurveList() +{ + _curveListValid = 0; + update(); // schedule repaint +} + + +void +CEGraphUI::invalidateSelection() +{ + update(); // schedule repaint +} + + +void +CEGraphUI::invalidateView() +{ + _viewValid = 0; + for (int i = 0; i < (int) _curves.size(); i++) { + _curves[i]->invalidateView(); + } + update(); // schedule repaint +} + + +void +CEGraphUI::invalidateTimeMode() +{ + update(); // schedule repaint +} + + +void CEGraphUI::updateView() +{ + double vx, vy, vw, vh; + _tool->getView(vx, vy, vw, vh); + _view.setView(vx, vy, vw, vh, + _scalesWidth, _scalesHeight, + width()-_scalesWidth, height()-_scalesHeight); +} + + +void CEGraphUI::updateCurves() +{ + // just clear and rebuild the curve list (optimize later if needed) + clearCurves(); + + CETool::AnimCurveList curves; + _tool->getCurves(curves); + _curves.reserve(curves.size()); + + for (int i = 0; i < (int)curves.size(); i++) { + _curves.push_back(new CEGraphCurve(this, curves[i], i)); + } + _curveListValid = 1; +} + + + + + + + + + + + diff --git a/src/SeExprEditor/CE/CEGraphUI.h b/src/SeExprEditor/CE/CEGraphUI.h new file mode 100644 index 00000000..f4f81f30 --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphUI.h @@ -0,0 +1,184 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CEGraphUI.h +* @brief Contains the declaration of class CEGraphUI. +*/ + +#ifndef CEGraphUI_h +#define CEGraphUI_h + +#include + +#include +#include +//qt3 #include +#include "CEGraphView.h" + +class CETool; +class CEGraphCurve; +class CEGraphSeg; +class CEGraphKey; +class CEDragHandler; + +class QFont; +class QColor; +class QEvent; +class QResizeEvent; +class QMouseEvent; + + +//**************************************************************************** +/** + * @class CEGraphUI + * @brief Insert one-line brief description of class CEGraphUI here. + * + * Insert detailed description of class CEGraphUI definition here. + * + * @author brentb + * + * @version 1.0 brentb 2001.11.20: Initial version of class CEGraphUI. + * @version 2.0 bsilva 2001.10.11: Ported to Qt4. + * + */ + +class CEGraphUI : + public QGLWidget +{ + Q_OBJECT + +public: + /// Constructor + CEGraphUI(QWidget* parent, CETool* tool); + /// Destructor + virtual ~CEGraphUI(); + + // view position in (x:frames, y:curve units) + const CEGraphView& getView(); + + CETool* tool() { return _tool; } + void moveSelBox(int x1, int y1, int x2, int y2); + void hideSelBox(); + enum ColorType { + BgColor, ScaleBgColor, ScaleColor, GridColor, TimebarColor, + OverlayColor, SelectedColor, HiSelectedColor, + CurveColor, HiCurveColor, NumColors }; + void setColor(ColorType color); + const QColor& getColor(ColorType color); + void getActivePart(int& curve, int& seg, int& part) + { curve = _activeCurve; seg = _activeSeg; part = _activePart; } + CEGraphCurve* getCurve(int curve); + CEGraphSeg* getSeg(int curve, int seg); + CEGraphKey* getKey(int curve, int seg); + int doSelectModeRender(int x1, int x2, int y1, int y2, + GLuint* buffer, int bufsize); + + virtual QSize minimumSizeHint() const { return QSize(200, 200); } + +public slots: + + /// Notification methods (from CETool) + void invalidateCurve(int index); + void invalidateCurveList(); + void invalidateSelection(); + void invalidateView(); + void invalidateTimeMode(); + +// void show(); + +protected: + /// overrides of QGLWidget methods + virtual void initializeGL(); + virtual void resizeGL(int w, int h); + virtual void resizeOverlayGL(int w, int h); + virtual void paintGL(); + virtual void paintOverlayGL(); + + virtual void resizeEvent(QResizeEvent *e); + virtual void mousePressEvent(QMouseEvent* e); + virtual void mouseDoubleClickEvent(QMouseEvent* e); + virtual void mouseMoveEvent(QMouseEvent* e); + virtual void mouseReleaseEvent(QMouseEvent* e); + virtual void enterEvent(QEvent* e); + virtual void leaveEvent(QEvent* e); + virtual void keyPressEvent(QKeyEvent *event); + + + void printStringAt(double x, double y, const char* str); + +private: + /// No definition by design, so accidental copying is prevented. + CEGraphUI ( const CEGraphUI& ); + /// No definition by design, so accidental assignment is prevented. + CEGraphUI& operator=( const CEGraphUI& ); + + void getNextIncrement(double min, int timeMode, + double& increment, int& numDecimalPlaces); + void getNextTickIncrement(double increment, int timeMode, + double& tickIncrement); + void paintScales(); + void paintCurves(); + void paintOverlay(bool erase=0); + void paintCrossHairs(); + void paintSelBox(); + void paintTimeBar(double frame); + + void moveCrossHairs(int x, int y); + void hideCrossHairs(); + + void pickActive(int x, int y); + + void updateView(); + void updateCurves(); + void clearCurves(); + + CETool* _tool; + QColor _colors[NumColors]; + + QFont _font; + int _fontListBase; + int _fontListCount; + + // size of scales area (bottom and left of widget), based on font + int _scalesWidth; + int _scalesHeight; + + // current view + CEGraphView _view; + bool _viewValid; + + // crosshair data + bool _showCrossHairs; + int _crossX, _crossY; + + // selection box data + bool _showSelBox; + int _selBoxX1, _selBoxY1, _selBoxX2, _selBoxY2; + + // curve list data + bool _curveListValid; + std::vector _curves; + + // active object data + int _activeCurve; + int _activeSeg; + int _activePart; + + // active drag handler + CEDragHandler* _dragHandler; +}; + +#endif //CEGraphUI_h diff --git a/src/SeExprEditor/CE/CEGraphView.h b/src/SeExprEditor/CE/CEGraphView.h new file mode 100644 index 00000000..39ffb833 --- /dev/null +++ b/src/SeExprEditor/CE/CEGraphView.h @@ -0,0 +1,92 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef CEGraphView_h +#define CEGraphView_h + +#include + +class CEGraphView { +public: + CEGraphView() + : _vx(0), _vy(0), _vw(1), _vh(1), + _px(0), _py(0), _pw(1), _ph(1) {} + void setView(double vx, double vy, double vw, double vh, + int px, int py, int pw, int ph) + { + _vx = vx; + _vy = vy; + _vw = vw; + _vh = vh; + _px = px; + _py = py; + _pw = pw; + _ph = ph; + _pixWidth = _vw / _pw; + _pixHeight = _vh / _ph; + _vxScale = _pw / _vw; + _vyScale = _ph / _vh; + _vxTrans = (_vw/2 - _vx) * (_pw/_vw) + _px; + _vyTrans = (_vh/2 - _vy) * (_ph/_vh) + _py; + } + + // view rectangle in view coords (x,y is center of view) + double vx() const { return _vx; } + double vy() const { return _vy; } + double vw() const { return _vw; } + double vh() const { return _vh; } + + // sides of view rectangle + double left() const { return _vx - _vw/2; } + double right() const { return _vx + _vw/2; } + double bottom() const { return _vy - _vh/2; } + double top() const { return _vy + _vh/2; } + + // view rectangle in pixel coords (x,y is offset of view in window) + int px() const { return _px; } + int py() const { return _py; } + int pw() const { return _pw; } + int ph() const { return _ph; } + + // pixel size in view units + double pixelWidth() const { return _pixWidth; } + double pixelHeight() const { return _pixHeight; } + + // view coord to pix coord conversion + double pxd(double vx) const { return vx * _vxScale + _vxTrans; } + double pyd(double vy) const { return vy * _vyScale + _vyTrans; } + int px(double vx) const { return int(floor(vx * _vxScale + _vxTrans)); } + int py(double vy) const { return int(floor(vy * _vyScale + _vyTrans)); } + + // pix coord to view coord conversion + double vx(int px) const { return (px - _vxTrans) / _vxScale; } + double vy(int py) const { return (py - _vyTrans) / _vyScale; } + +private: + double _vx, _vy; // center of view in view units + double _vw, _vh; // size of view in view units + int _px, _py; // offset of view in window + int _pw, _ph; // size of view in pixels + double _pixWidth; // width of pixel in view units + double _pixHeight; // height of pixel in view units + double _vxScale; // x scale factor for view to pix conversion + double _vyScale; // y scale factor for view to pix conversion + double _vxTrans; // x translation factor for view to pix conversion + double _vyTrans; // y translation factor for view to pix conversion +}; + + +#endif diff --git a/src/SeExprEditor/CE/CEMainUI.cpp b/src/SeExprEditor/CE/CEMainUI.cpp new file mode 100644 index 00000000..6a325bc4 --- /dev/null +++ b/src/SeExprEditor/CE/CEMainUI.cpp @@ -0,0 +1,97 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CEMainUI.C +* @brief Contains the Definition of class CEMainUI. +*/ + +//qt3 #include +//qt3 #include + +#include +#include +#include +#include +#include + +#include + +#include "CECurveListUI.h" +#include "CEGraphUI.h" +#include "CESegEditUI.h" +#include +#include "CEMainUI.h" + +/** + * Constructor. + */ +CEMainUI::CEMainUI(QWidget* parent, CETool* tool) + : QWidget(parent), _tool(tool) +{ + setObjectName("CurveEditor"); + + QVBoxLayout* layout = new QVBoxLayout(this); +//qt3 layout->setAutoAdd(true); + layout->setContentsMargins(4, 4, 4, 4); // widget border + layout->setSpacing(4); // space between sub-widgets + + // top area is split horizontally, then the left half is split vertically + QSplitter* hsplit = new QSplitter(this); + QSplitter* vsplit = new QSplitter(Qt::Vertical, hsplit); + + hsplit->setContentsMargins(0,0,0,0); + vsplit->setContentsMargins(0,0,0,0); + + // create the sub-widgets + _curveListUI = new CECurveListUI(vsplit, tool); + _graphUI = new CEGraphUI(hsplit, tool); + _segEditUI = new CESegEditUI(this, tool); + + _curveListUI->setContentsMargins(0,0,0,0); + //_segListUI->setContentsMargins(0,0,0,0); + _segEditUI->setContentsMargins(0,0,0,0); + + // default splitter sizes + QList sizes; + sizes.push_back(1); sizes.push_back(1); + hsplit->setSizes(sizes); + + _graphUI->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + + vsplit->addWidget(_curveListUI); + vsplit->addWidget(_segEditUI); + hsplit->addWidget(vsplit); + hsplit->addWidget(_graphUI); + + layout->addWidget(hsplit); + // make splitters resize nicely +//qt3 hsplit->setResizeMode(vsplit, QSplitter::KeepSize); + hsplit->setStretchFactor(hsplit->indexOf(vsplit), 0); + hsplit->setStretchFactor(hsplit->indexOf(_graphUI), 1); + + hsplit->setSizes(sizes); + + this->show(); +} + +/** + * Destructor. + */ +CEMainUI::~CEMainUI() +{ + // TODO - stash splitter sizes in tool for remapping +} diff --git a/src/SeExprEditor/CE/CEMainUI.h b/src/SeExprEditor/CE/CEMainUI.h new file mode 100644 index 00000000..5ac01207 --- /dev/null +++ b/src/SeExprEditor/CE/CEMainUI.h @@ -0,0 +1,70 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CEMainUI.h +* @brief Contains the declaration of class CEMainUI. +*/ + +#ifndef CEMainUI_h +#define CEMainUI_h + +// Base Class Includes +//qt3 #include +#include + +class QLabel; + +class CETool; +class CEGraphUI; +class CECurveListUI; +class CESegEditUI; + +//**************************************************************************** +/** + * @class CEMainUI + * @brief Main GUI User interface class for the curve editor + * + * + * @author brentb + * + * @version 1.0 brentb 11/20/2001: Initial version of class CEMainUI. + * + */ + +class CEMainUI : public QWidget +{ +public: + + /// Constructor + CEMainUI(QWidget* parent, CETool* tool); + /// Destructor + virtual ~CEMainUI(); + +protected: + + /// No definition by design, so accidental copying is prevented. + CEMainUI ( const CEMainUI& ); + /// No definition by design, so accidental assignment is prevented. + CEMainUI& operator=( const CEMainUI& ); + +private: + CETool* _tool; + CEGraphUI* _graphUI; + CECurveListUI* _curveListUI; + CESegEditUI* _segEditUI; +}; + +#endif //CEMainUI_h diff --git a/src/SeExprEditor/CE/CESegEditUI.cpp b/src/SeExprEditor/CE/CESegEditUI.cpp new file mode 100644 index 00000000..f186ecf2 --- /dev/null +++ b/src/SeExprEditor/CE/CESegEditUI.cpp @@ -0,0 +1,494 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CESegEditUI.C +* @brief Contains the Definition of class CESegEditUI. +*/ + +/* qt3 +#include +#include +#include +#include +#include +#include +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CETool.h" +#include "CESegEditUI.h" + + +MyTextEdit::MyTextEdit(QWidget* parent) +:QTextEdit(parent),editing(false) +{} + +void MyTextEdit::keyPressEvent( QKeyEvent* e ) +{ + // Accept expression + if (e->key()==Qt::Key_Return || e->key()==Qt::Key_Enter){ + selectAll(); + finishEdit(); + return; + }else if (e->key()==Qt::Key_Escape){ + setText(savedText); + selectAll(); + finishEdit(); + return; + }else if(e->key()==Qt::Key_Tab){ + QWidget::keyPressEvent(e); + return; + }else if(!editing){ + editing=true; + setColor(true); + savedText=toPlainText(); + } + QTextEdit::keyPressEvent(e); +} + +void MyTextEdit::setColor(bool editing) +{ +} + +void MyTextEdit::finishEdit() +{ + editing=false; + setColor(false); + emit editingFinished(); +} + +void MyTextEdit::focusOutEvent(QFocusEvent* e) +{ + //setTextCursor(QTextCursor()); + finishEdit(); + QTextCursor newCursor=textCursor(); + newCursor.clearSelection(); + setTextCursor(newCursor); + setColor(false); + QTextEdit::focusOutEvent(e); +} + + +namespace { + + const char* TypeToLabel(const char* type) + { + if (!strcmp(type, "")) return "expr"; + else if (!strcmp(type, "t")) return "tweak"; + + return type; + } + + const char* LabelToType(const char* label) + { + if (!strcmp(label, "expr")) return ""; + else if (!strcmp(label, "tweak")) return "t"; + + return label; + } +} + + +static const int EditMinWidth = 30; +static const int EditMaxWidth = 65; +static const int EditPad = 3; + +static const int MaxParams = 4; + + +struct TangTypesEntry{ + const char* name; + animlib::AnimKeyframe::tangentType type; +} TangTypes[] = { + {"fixed",animlib::AnimKeyframe::kTangentFixed}, + {"auto",animlib::AnimKeyframe::kTangentAuto}, + //{"global",animlib::AnimKeyframe::kTangentGlobal}, + {"linear",animlib::AnimKeyframe::kTangentLinear}, + {"flat",animlib::AnimKeyframe::kTangentFlat}, + {"step",animlib::AnimKeyframe::kTangentStep}, + {"stepnext",animlib::AnimKeyframe::kTangentStepNext}, + //{"slow",animlib::AnimKeyframe::kTangentSlow}, + //{"fast",animlib::AnimKeyframe::kTangentFast}, + {"spline",animlib::AnimKeyframe::kTangentSmooth}, + //{"clamped",animlib::AnimKeyframe::kTangentClamped}, + //{"plateau",animlib::AnimKeyframe::kTangentPlateau}, + {0,animlib::AnimKeyframe::kTangentGlobal} +}; +struct InfinityTypesEntry{ + const char* name; + animlib::AnimCurve::infinityType type; +} InfinityTypes[] = { + {"constant",animlib::AnimCurve::kInfinityConstant}, + {"linear",animlib::AnimCurve::kInfinityLinear}, + {"cycle",animlib::AnimCurve::kInfinityCycle}, + {"cycleRelative",animlib::AnimCurve::kInfinityCycleRelative}, + {"oscillate",animlib::AnimCurve::kInfinityOscillate}, + {0,animlib::AnimCurve::kInfinityConstant} +}; + + + + + +MyTextEdit* CESegEditUI::addEdit(QGridLayout* grid,int row,int col,const QString& label) +{ + MyTextEdit* edit=new MyTextEdit(this); + edit->setFixedWidth(EditMaxWidth*1.5); + edit->setFixedHeight(25); + edit->setContentsMargins(0,0,0,0); + grid->addWidget(new QLabel(label), row, col); + grid->addWidget(edit,row+1,col); + connect(edit, SIGNAL(editingFinished()), SLOT(handleChanged())); + + return edit; +} + +QComboBox* CESegEditUI::addCombo(QGridLayout* grid,int row,int col,const QString& label) +{ + QComboBox* combo; + combo=new QComboBox(); + auto it=&TangTypes[0]; + while(it->name != 0){ + combo->addItem(it->name); + ++it; + } + grid->addWidget(new QLabel(label),row,col); + grid->addWidget(combo,row+1,col); + connect(combo,SIGNAL(currentIndexChanged(int)),SLOT(handleChanged())); + return combo; +} + +QComboBox* CESegEditUI::addComboInfinity(QGridLayout* grid,int row,int col,const QString& label) +{ + QComboBox* combo; + combo=new QComboBox(); + auto it=&InfinityTypes[0]; + while(it->name != 0){ + combo->addItem(it->name); + ++it; + } + grid->addWidget(new QLabel(label),row,col); + grid->addWidget(combo,row+1,col); + connect(combo,SIGNAL(currentIndexChanged(int)),SLOT(handleInfinityChanged())); + return combo; +} + + +/** + * Currently the default constructor does nothing. + */ +CESegEditUI::CESegEditUI(QWidget* parent, CETool* tool) : + QWidget(parent), _tool(tool), + _valid(0), _updating(0) +{ + setObjectName("SegEdit"); + setContentsMargins(0,0,0,0); + + setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::Fixed)); + + QGroupBox* box1=new QGroupBox("Full Curve"); + QGridLayout* grid1 = new QGridLayout; + grid1->setContentsMargins(0,0,0,0); + grid1->setMargin(5); + grid1->setSpacing(0); + box1->setLayout(grid1); + + QGroupBox* box2=new QGroupBox("Key Info"); + QGridLayout* grid2 = new QGridLayout; + grid2->setContentsMargins(0,0,0,0); + grid2->setMargin(5); + grid2->setSpacing(0); + box2->setLayout(grid2); + + _weighted=new QCheckBox("Weighted"); + connect(_weighted,SIGNAL(stateChanged(int)),SLOT(weightedChanged(int))); + grid1->addWidget(_weighted,2,0); + grid1->addWidget(new QLabel("(not\nrecommended)"),2,1); + _preInfinity=addComboInfinity(grid1,0,0,"PreInf"); + _postInfinity=addComboInfinity(grid1,0,1,"PostInf"); + _frame=addEdit(grid2,0,0,"Frame"); + _value=addEdit(grid2,0,1,"Value"); + _inAngle=addEdit(grid2,2,0,"InAngle"); + _inWeight=addEdit(grid2,4,0,"InWeight"); + _outAngle=addEdit(grid2,2,1,"OutAngle"); + _outWeight=addEdit(grid2,4,1,"OutWeight"); + _inType=addCombo(grid2,6,0,"InType"); + _outType=addCombo(grid2,6,1,"OutType"); + _locked=new QCheckBox("Locked"); + connect(_locked,SIGNAL(stateChanged(int)),SLOT(lockedChanged(int))); + grid2->addWidget(_locked,8,0); + + QVBoxLayout* lay=new QVBoxLayout; + lay->setSpacing(0); + lay->setMargin(0); + setLayout(lay); + lay->addWidget(box1); + lay->addWidget(box2); + + + connect(_tool, SIGNAL(curveChanged(int)), SLOT(invalidateCurve(int))); + connect(_tool, SIGNAL(curveListChanged()), SLOT(invalidate())); + connect(_tool, SIGNAL(selectionChanged()), SLOT(invalidate())); + + doUpdate(); +} + +/** + * Destructor. + */ +CESegEditUI::~CESegEditUI() +{ + //delete [] _params; +} + + +void +CESegEditUI::invalidateCurve(int index) +{ + if (index == _curveIndex) + invalidate(); +} + + +void +CESegEditUI::invalidate() +{ + if (_updating) return; // prevent circular update! + if (_valid) { + _valid = 0; + update(); + } +} + + +void +CESegEditUI::paintEvent(QPaintEvent* event) +{ + if (!_valid) doUpdate(); + QWidget::paintEvent(event); +} + + +void +CESegEditUI::doUpdate() +{ + _updating = 1; + // see if we have 1 and only 1 curve selected + msg::list sel; + _tool->getSelection(sel); + if (sel.size() == 2) + { + // 1 curve - sel[0] is curveIndex, sel[1] is list of segs + msg::list segs = sel[1]; + _curveIndex = sel[0]; + //msg::RcvrId curve; + animlib::AnimCurve* curve; + _tool->getCurve(curve, _curveIndex); + _curve = curve; // bind to iSgExpr interface + + // edit seg if only 1 seg is selected (or there's only 1 seg) + if (segs.size() == 1) { + _segIndex = segs[0]; + } + else + { + int numSegs = 0; + numSegs=_curve->getNumKeys(); + if (numSegs == 1) + _segIndex = 0; + else _segIndex = -1; + } + } + else + { + _curveIndex = -1; + _segIndex = -1; + _curve = 0; // msg::RcvrId(); + } + + // enable/disable edit controls as appropriate + if (_curveIndex==-1 || _segIndex==-1) + disableControls(); + else + enableControls(); + + if(_curveIndex==-1){ + _preInfinity->setEnabled(0); + _postInfinity->setEnabled(0); + }else{ + enableInfinityType(_preInfinity,_curve->getPreInfinity()); + _preInfinity->setEnabled(1); + enableInfinityType(_postInfinity,_curve->getPostInfinity()); + _postInfinity->setEnabled(1); + _weighted->setEnabled(1); + _weighted->setChecked(_curve->isWeighted()); + } + + _valid = 1; + _updating = 0; +} + +namespace{ +void disableEdit(MyTextEdit* w){w->setEnabled(0);w->setText("");} +} +void +CESegEditUI::disableControls() +{ + disableEdit(_frame); + disableEdit(_value); + disableEdit(_inAngle); + disableEdit(_outAngle); + disableEdit(_inWeight); + disableEdit(_outWeight); + _inType->setEnabled(0); + _outType->setEnabled(0); + + //_type->setEnabled(_segIndex != 0); + + _frame->setText(""); + _value->setText(""); + +//qt3 _type->setCurrentText(""); + //_type->setEditText(""); + + //for (int i = 0; i < MaxParams; i++) + // _params[i]->hide(); +} + +void CESegEditUI::enableTangType(QComboBox* combo,animlib::AnimKeyframe::tangentType type,bool enable) +{ + auto it=&TangTypes[0]; + int index=0; + while(TangTypes[index].name != 0){ + if(TangTypes[index].type==type){ + combo->setCurrentIndex(index); + combo->setEnabled(enable); + return; + }else{ + combo->setCurrentIndex(0); // fixed + combo->setEnabled(enable); + } + index++; + } +} + +void CESegEditUI::enableInfinityType(QComboBox *combo,animlib::AnimCurve::infinityType type) +{ + auto it=&TangTypes[0]; + int index=0; + while(InfinityTypes[index].name != 0){ + if(InfinityTypes[index].type==type){ + combo->setCurrentIndex(index); + break; + } + index++; + } +} + +namespace{ + void setTextAndEnable(MyTextEdit* edit,double val,bool enableState=true){ + edit->setText(QString().sprintf("%g", val)); + edit->setEnabled(enableState); + if(edit->hasFocus()) edit->selectAll(); + } +} +void +CESegEditUI::enableControls() +{ + double frame; + msg::str expr; + msg::str type; + msg::list params; + animlib::AnimKeyframe& key=*(_curve->getFirstKey()+_segIndex); + + double val=key.getValue(); + frame=key.getTime(); + + //_curve.getSegment(frame, expr, type, params, _segIndex); + bool preseg = false; // _segIndex == 0; + + + setTextAndEnable(_frame,key.getTime()); + setTextAndEnable(_value,key.getValue()); + setTextAndEnable(_inAngle,key.getInAngle()); + setTextAndEnable(_outAngle,key.getOutAngle()); + setTextAndEnable(_inWeight,key.getInWeight(),_curve->isWeighted()); + setTextAndEnable(_outWeight,key.getOutWeight(),_curve->isWeighted()); + setTextAndEnable(_frame,key.getTime()); + _locked->setChecked(key.isLocked()); + enableTangType(_inType,key.getInTangentType(),!key.isLocked()); + enableTangType(_outType,key.getOutTangentType(),true); + + +} + +void CESegEditUI::handleInfinityChanged(){ + if(_updating) return; + if(_curveIndex<0) return; + + _tool->setSelectedInfinity(InfinityTypes[_preInfinity->currentIndex()].type, + InfinityTypes[_postInfinity->currentIndex()].type); +} + +void CESegEditUI::handleChanged() +{ + if(_updating) return; + if(_curveIndex<0) return; + bool ok=0; + double frame = _frame->toPlainText().toDouble(&ok); + if(!ok) {std::cerr<<"frame is invalid"<toPlainText().toDouble(&ok); + if(!ok) {std::cerr<<"value is invalid"<toPlainText().toDouble(&ok); + if(!ok) {std::cerr<<"inAngle is invalid"<toPlainText().toDouble(&ok); + if(!ok) {std::cerr<<"outAngle is invalid"<toPlainText().toDouble(&ok); + if(!ok) {std::cerr<<"inWeight is invalid"<toPlainText().toDouble(&ok); + if(!ok) {std::cerr<<"outWeight is invalid"<isChecked(); + animlib::AnimKeyframe::tangentType inType=TangTypes[_inType->currentIndex()].type; + animlib::AnimKeyframe::tangentType outType=TangTypes[_outType->currentIndex()].type; + if(locked) inType=outType; + + _tool->setSelectedSegment(frame,value,inAngle,outAngle,inWeight,outWeight,inType,outType); +} + +void CESegEditUI::weightedChanged(int val) +{ + if(_updating) return; + if(_curveIndex<0) return; + + _tool->setSelectedWeighted(val); +} + +void CESegEditUI::lockedChanged(int val) +{ + if(_updating) return; + if(_curveIndex<0) return; + + _tool->setSelectedLocked(val); +} diff --git a/src/SeExprEditor/CE/CESegEditUI.h b/src/SeExprEditor/CE/CESegEditUI.h new file mode 100644 index 00000000..ca4ff2c8 --- /dev/null +++ b/src/SeExprEditor/CE/CESegEditUI.h @@ -0,0 +1,140 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CESegEditUI.h +* @brief Contains the declaration of class CESegEditUI. +*/ + +#ifndef CESegEditUI_h +#define CESegEditUI_h + + +//qt3 #include +#include +#include +#include +#include +class CETool; +class QComboBox; +class QLineEdit; +class QGridLayout; +class QCheckBox; + +namespace animlib{ +class AnimCurve; +} + +class MyTextEdit:public QTextEdit +{ + Q_OBJECT; + + + bool editing; + QString savedText; + +public: + MyTextEdit(QWidget* parent); + + virtual void keyPressEvent(QKeyEvent* e); + virtual void focusOutEvent(QFocusEvent* e); + + void setColor(bool editing); + void finishEdit(); +signals: + void editingFinished(); + + +}; + + +//**************************************************************************** +/** + * @class CESegEditUI + * @brief Insert one-line brief description of class CESegEditUI here. + * + * Insert detailed description of class CESegEditUI definition here. + * + * @author brentb + * + * @version 1.0 brentb 11/20/2001: Initial version of class CESegEditUI. + * + */ + +class CESegEditUI : public QWidget +{ + Q_OBJECT + +public: + /// Constructor + CESegEditUI(QWidget* parent, CETool* tool); + /// Destructor + virtual ~CESegEditUI(); + +private slots: + /// Notification methods + void invalidateCurve(int index); + void invalidate(); + void handleChanged(); + void handleInfinityChanged(); + void weightedChanged(int val); + void lockedChanged(int val); + //void handle + //void handleFrameChanged(); + //void handleValueChanged(); + //void handleTypeChanged(); + //void handleParamChanged(); + +private: + /// No definition by design, so accidental copying is prevented. + CESegEditUI(const CESegEditUI&); + /// No definition by design, so accidental assignment is prevented. + CESegEditUI& operator=(const CESegEditUI&); + + /// QWidget override + virtual void paintEvent (QPaintEvent* event); + + /// Update state from tool/curve data + void doUpdate(); + void disableControls(); + void enableControls(); + + MyTextEdit* addEdit(QGridLayout* layout,int row,int col,const QString& label); + QComboBox* addCombo(QGridLayout* grid,int row,int col,const QString& label); + QComboBox* addComboInfinity(QGridLayout* grid,int row,int col,const QString& label); + void enableTangType(QComboBox* combo,animlib::AnimKeyframe::tangentType type,bool eanble); + void enableInfinityType(QComboBox* combo,animlib::AnimCurve::infinityType type); + + CETool* _tool; + QCheckBox* _weighted; + QComboBox *_preInfinity,*_postInfinity; + MyTextEdit *_frame; + MyTextEdit *_value; + MyTextEdit *_inAngle,*_outAngle; + MyTextEdit *_inWeight,*_outWeight; + QComboBox *_inType,*_outType; + QCheckBox *_locked; + //QComboBox* _type; + //QLineEdit* _typeEntry; + //QLineEdit** _params; + bool _valid; + bool _updating; + int _curveIndex; + animlib::AnimCurve* _curve; + int _segIndex; + int _numParams; +}; + +#endif //CESegEditUI_h diff --git a/src/SeExprEditor/CE/CETool.cpp b/src/SeExprEditor/CE/CETool.cpp new file mode 100644 index 00000000..c908aabd --- /dev/null +++ b/src/SeExprEditor/CE/CETool.cpp @@ -0,0 +1,1134 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CETool.C +* @brief Contains the Definition of class CETool. +*/ + +#include +#include +#include +#include +#include +#include +#include "CEMainUI.h" +#include "CETool.h" + +namespace { + inline double clamp(double x, double min, double max) { + return x < min ? min : x > max ? max : x; + } +} + +void keyUpdated(animlib::AnimCurve* curve,int key); +void keysUpdated(animlib::AnimCurve* curve,int keyStart,int keyEnd,bool regenerateWeights); + +/** + * Constructor + */ +CETool::CETool() + : _ui(0), _vx(50), _vy(50), _vw(100), _vh(100), + _timeMode(0), _selectedCurve(-1), _selListValid(0) +{ +// _rcvrid.addIRcvr(static_cast(this)); +// _rcvrid.addIRcvr(static_cast(this)); +} + +/** + * Destructor + */ +CETool::~CETool() +{ + // todo - consolidate removeObserver into CurveData dtor + CurveList::iterator i; + for (i = _curves.begin(); i != _curves.end(); i++) { + delete *i; + // TODO: remove observer + } +} + + +err::Result +CETool::newCurve(msg::cstr name) +{ + // TODO: add create curve back +#if 0 + iSgExpr expr; + EFAIL(iFactory().createInstance(expr, "iSgExpr", msg::value()), + "Can't create curve. Expr library not loaded?"); + if (!expr) return err::Result(errINTERNAL, "newCurve failed"); + addCurveInternal(expr, name); +#endif + return errSUCCESS; +} + + +// TODO: add curve +err::Result +CETool::addCurve(animlib::AnimCurve* curve) +{ +#if 0 + // get name as "node.parameter" + iSgParam param; + EFAIL(expr.getParent(param), "Can't get expr param"); + EFAILIF(!param, "addCurve failed, expr parent doesn't support iSgParam"); + msg::str name; + EFAIL(param.getName(name), "Can't get param name"); + iSgNode node; + EFAIL(param.getNode(node), "Can't get node from param"); + msg::str nodename; + std::string cname; + if (node) { + node.getName(nodename); + cname << nodename << "." << name; + } + else cname = name; +#endif + + addCurveInternal(curve, "curvename"); + + //i23-206 Send To CE should Auto Fit + int curveIndex = findCurve(curve); + selectCurve(curveIndex); + frameSelection(); + + return errSUCCESS; +} + + +void +CETool::addCurveInternal(animlib::AnimCurve* curve, const char* name) +{ +// TODO: add curve + if (!name || !name[0]) name = "Curve"; + + // uniquify name + const char* basename = name; + int suffix = 1; + std::string tmpName=name; + while (findCurve(tmpName.c_str()) >= 0) { + suffix++; + std::stringstream ss; + ss<animCurve = curve; + curveData->name = tmpName; + curveData->ypan = 0; + curveData->yzoom = 1; + curveData->selected = 0; + curveData->numSegs = 0; + curveData->numSegs=curve->getNumKeys(); + _curves.push_back(curveData); + // TODO: we need an observer fix + //curve->expr.addObserver(_rcvrid); + emit curveListChanged(); +} + +err::Result +CETool::removeCurve(int curveIndex) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + + //CurveData* curve = _curves[curveIndex]; + //curve->expr.removeObserver(_rcvrid); + //delete curve; + delete _curves[curveIndex]; + _curves.erase(_curves.begin()+curveIndex); + _selListValid = 0; + emit curveListChanged(); + return errSUCCESS; +} + + +err::Result +CETool::removeSelectedCurves() +{ + CurveList::iterator i; + for (i = _curves.begin(); i != _curves.end();) { + CurveData* curve = *i; + if (curve->selected) { + //curve->expr.removeObserver(_rcvrid); + delete curve; + i = _curves.erase(i); + } + else i++; + } + _selListValid = 0; + emit curveListChanged(); + return errSUCCESS; +} + + +err::Result +CETool::removeAllCurves() +{ + if (_curves.size()) { + CurveList::iterator i; + for (i = _curves.begin(); i != _curves.end(); i++) { + CurveData* curve = *i; + //curve->expr.removeObserver(_rcvrid); + delete curve; + } + _curves.clear(); + _selListValid = 0; + emit curveListChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::findCurve(int& curveIndex, msg::cstr name) +{ + for (int i = 0; i < numCurves(); i++) { + if (_curves[i]->name == name) { + curveIndex = i; + return errSUCCESS; + } + } + return errNOTFOUND; +} + +err::Result +CETool::getCurve(animlib::AnimCurve*& animCurve, int curveIndex) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + animCurve = _curves[curveIndex]->animCurve; + return errSUCCESS; +} + + +err::Result +CETool::getCurves(AnimCurveList& curves) +{ + curves.clear(); + curves.resize(numCurves()); + for (int i = 0; i < numCurves(); i++) { + curves[i]=_curves[i]->animCurve; + } + return errSUCCESS; +} + + +err::Result +CETool::getCurveNames(std::vector& names) +{ + names.clear(); + for (int i = 0; i < numCurves(); i++) { + names.push_back(_curves[i]->name); + } + return errSUCCESS; +} + + + +err::Result +CETool::selectCurve(int curveIndex) +{ + ECHK(clearSelection()); + return selectAddCurve(curveIndex); +} + + +err::Result +CETool::selectAddCurve(int curveIndex) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + CurveData* curve = _curves[curveIndex]; + if (!curve->selected || + (int) curve->segsSelected.size() != curve->numSegs) + { + _selListValid = 0; + curve->selected = 1; + for (int i = 0; i < curve->numSegs; i++) + curve->segsSelected.insert(i); + emit selectionChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::deselectCurve(int curveIndex) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + CurveData* curve = _curves[curveIndex]; + if (curve->selected) { + curve->segsSelected.clear(); + curve->selected = 0; + _selListValid = 0; + emit selectionChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::clearSelection() +{ + bool changed = 0; + for (int i = 0; i < numCurves(); i++) { + CurveData* curve = _curves[i]; + if (curve->selected) { + curve->segsSelected.clear(); + curve->selected = 0; + changed = 1; + } + } + if (changed) { + _selListValid = 0; + emit selectionChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::selectSegment(int curveIndex, int segIndex) +{ + ECHK(clearSelection()); + return selectAddSegment(curveIndex, segIndex); +} + + +err::Result +CETool::selectAddSegment(int curveIndex, int segIndex) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + CurveData* curve = _curves[curveIndex]; + + // validate first + if (segIndex < 0 || segIndex >= curve->numSegs) return errINDEX; + + // then apply + bool changed = 0; + if (!curve->selected || !curve->segsSelected.count(segIndex)) { + curve->segsSelected.insert(segIndex); + curve->selected = 1; + changed = 1; + } + if (changed) { + _selListValid = 0; + emit selectionChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::deselectSegment(int curveIndex, int segIndex) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + CurveData* curve = _curves[curveIndex]; + + bool changed = 0; + if (curve->segsSelected.count(segIndex)) { + curve->segsSelected.erase(segIndex); + changed = 1; + } + if (changed) { + _selListValid = 0; + emit selectionChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::selectCurves(msg::list curveIndices) +{ + // validate first + int ncurves = numCurves(); + bool* newState = (bool*) alloca(sizeof(bool)*ncurves); + memset(newState, 0, sizeof(bool)*ncurves); + + int i; + for (i = 0; i < curveIndices.size(); i++) { + int curveIndex = curveIndices[i]; + if (curveIndex < 0 || curveIndex >= ncurves) + return errINDEX; + newState[curveIndex] = 1; + } + // apply + bool changed = 0; + for (i = 0; i < ncurves; i++) { + CurveData* curve = _curves[i]; + if (newState[i]) { + if (!curve->selected || + (int) curve->segsSelected.size() != curve->numSegs) + { + curve->selected = 1; + for (int i = 0; i < curve->numSegs; i++) + curve->segsSelected.insert(i); + changed = 1; + } + } + else { + if (curve->selected) { + curve->selected = 0; + curve->segsSelected.clear(); + changed = 1; + } + } + } + + if (changed) { + _selListValid = 0; + emit selectionChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::selectSegments(int curveIndex, msg::list segIndices) +{ + // validate first + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + CurveData* curve = _curves[curveIndex]; + int numSegs=curve->numSegs; + bool* newState = (bool*) alloca(sizeof(bool)*numSegs); + memset(newState, 0, sizeof(bool)*numSegs); + int i; + for (i = 0; i < segIndices.size(); i++) { + int segIndex = segIndices[i]; + if (segIndex < 0 || segIndex >= numSegs) + return errINDEX; + newState[segIndex] = 1; + } + // apply + bool changed = 0; + for (i = 0; i < numSegs; i++) { + bool selected = curve->selected && curve->segsSelected.count(i); + if (selected != newState[i]) { + if (newState[i]) { + curve->selected = 1; + curve->segsSelected.insert(i); + } else { + curve->segsSelected.erase(i); + } + changed = 1; + } + } + + if (changed) { + _selListValid = 0; + emit selectionChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::getSelection(msg::list& selections) +{ + if (!_selListValid) { + // rebuild selectionList + // first must count selections + int numCurveSel = 0; + for (int i = 0; i < numCurves(); i++) + if (_curves[i]->selected) numCurveSel++; + // make an entry for each selected curve + _selList.newlist(numCurveSel*2); + int index = 0; + for (int i = 0; i < numCurves(); i++) { + CurveData* curve = _curves[i]; + if (_curves[i]->selected) { + // build list of selected seg indices + msg::list segs(curve->segsSelected.size()); + std::set::iterator seg; + int segindex = 0; + for (seg = curve->segsSelected.begin(); + seg != curve->segsSelected.end(); + seg++) + { + segs.set(segindex++, *seg); + } + // add curve index and seg indices to selList + _selList.set(index++, i); + _selList.set(index++, segs); + } + } + _selListValid = 1; + } + selections = _selList; + return errSUCCESS; +} + + +err::Result +CETool::getSelectedCurve(int& curve) +{ + msg::list sellist; + ECHK(getSelection(sellist)); + int numcurves = sellist.size()/2; + EFAILIF(!numcurves, "No curve selected"); + EFAILIF(numcurves>1, "More than one curve selected"); + int index = sellist[0].asint(); + ERETIF(index < 0 || index >= (int)_curves.size(), + errINTERNAL, "Bad curve index"); + curve = index; + return errSUCCESS; +} + + +err::Result +CETool::getSelectedSegment(int& curve, int& seg) +{ + ECHK(getSelectedCurve(curve)); + CurveData* cdata = _curves[curve]; + int numsegs = cdata->segsSelected.size(); + EFAILIF(!numsegs, "No segment selected"); + EFAILIF(numsegs>1, "More than one curve selected"); + seg = *cdata->segsSelected.begin(); + return errSUCCESS; +} + + +err::Result +CETool::isSegmentSelected(bool& selected, int curveIndex, int segIndex) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + CurveData* curve = _curves[curveIndex]; + + if (segIndex < 0 || segIndex >= curve->numSegs) return errINDEX; + + selected = curve->selected && curve->segsSelected.count(segIndex) != 0; + return errSUCCESS; +} + + +int +CETool::insertKey(double frame) +{ + // TODO: fix + int curve; + if(getSelectedCurve(curve)==errSUCCESS){ + animlib::AnimCurve* animCurve=_curves[curve]->animCurve; + double val=animCurve->getValue(frame); + auto it=animCurve->addKey(frame,val); + it->setInTangentType(animlib::AnimKeyframe::kTangentAuto); + it->setOutTangentType(animlib::AnimKeyframe::kTangentAuto); + int segment=distance(animCurve->getFirstKey(),it); + keyUpdated(_curves[curve]->animCurve,segment); + _curves[curve]->numSegs=animCurve->getNumKeys(); + emit curveChanged(curve); + return segment ; + } + return -1; +} + + +void +CETool::setSegmentStr(msg::cstr str) +{ + // TODO: fix +#if 0 + int curve; + int seg; + ECHK(getSelectedSegment(curve, seg)); + return _curves[curve]->expr.setSegmentStr(seg, str); +#endif +} + +/* Operate on a selected segment */ +void +CETool::setSelectedSegmentFrame(double frame) +{ + // TODO: fix + int curve; + int seg; + if(getSelectedSegment(curve, seg) == errSUCCESS){ + _curves[curve]->animCurve->setTime(seg,frame); + emit curveChanged(curve); + } +} + + +void +CETool::setSelectedSegmentValue(double value) +{ + // TODO: fix + int curve; + int seg; + if(getSelectedSegment(curve, seg) == errSUCCESS){ + setSegmentValue(value, curve, seg); + } +} + + +void keysUpdated(animlib::AnimCurve* curve,int keyStart,int keyEnd,bool regenerateWeights){ + // compute derivatives based on spline rule (central differencing, left or right differencing) + // we are iterating over keys and gathering left and right neighbor + const double one_third=1./3.; + const double deg2rad=M_PI/180.,rad2deg=180./M_PI; + for(int i=keyStart;igetValue()-prev->getValue(); + hPrev=curr->getTime()-prev->getTime(); + } + if(next){ + deltaNext=next->getValue()-curr->getValue(); + hNext=next->getTime()-curr->getTime(); + } + // NOTE: this reduces to the one sided difference when we don't have prev or next + deriv=(deltaPrev+deltaNext)/(hNext+hPrev); + // now create clamped auto tangents + double clampedDeriv=deriv; + if(hPrev==0 || deltaPrev == 0) clampedDeriv=0; + else{ + double clampDelta=deltaPrev/hPrev; + clampedDeriv=clamp(clampedDeriv/clampDelta,0,3)*clampDelta; + } + if(hNext==0 || deltaNext == 0) clampedDeriv=0; + else{ + double clampDelta=deltaNext/hNext; + clampedDeriv=clamp(clampedDeriv/clampDelta,0,3)*clampDelta; + } + + animlib::AnimKeyframe::tangentType inTangentType=curr->getInTangentType(),outTangentType=curr->getOutTangentType(); + double inDeriv=0,outDeriv=0; + switch(inTangentType){ + case animlib::AnimKeyframe::kTangentFixed: break; //don't change them + case animlib::AnimKeyframe::kTangentSmooth: inDeriv=deriv;break; + case animlib::AnimKeyframe::kTangentAuto: inDeriv=clampedDeriv;break; + case animlib::AnimKeyframe::kTangentLinear: inDeriv=hPrev!=0?deltaPrev/hPrev:0;break; + case animlib::AnimKeyframe::kTangentFlat: inDeriv=0;break; + default: // don't know how to do this type, so pretend it doesn't exist! + inDeriv=0; + break; + } + switch(outTangentType){ + case animlib::AnimKeyframe::kTangentFixed: break; //don't change them + case animlib::AnimKeyframe::kTangentSmooth: outDeriv=deriv;break; + case animlib::AnimKeyframe::kTangentAuto: outDeriv=clampedDeriv;break; + case animlib::AnimKeyframe::kTangentLinear: outDeriv=hNext!=0?deltaNext/hNext:0;break; + case animlib::AnimKeyframe::kTangentFlat: outDeriv=0;break; + default: // don't know how to do this type, so pretend it doesn't exist! + outDeriv=0; + break; + } + + bool weighted=curve->isWeighted(); + if(next && outTangentType != animlib::AnimKeyframe::kTangentFixed){ + double outAngle=atan(outDeriv); + curr->setOutAngle(rad2deg*outAngle); + curr->setOutWeight(weighted ? hNext*one_third/cos(outAngle) : 1); + } + if(inTangentType != animlib::AnimKeyframe::kTangentFixed && prev){ + double inAngle=atan(inDeriv); + curr->setInAngle(rad2deg*inAngle); + curr->setInWeight(weighted ? hPrev*one_third/cos(inAngle) : 1); + } + + if(regenerateWeights){ + if(weighted){ + double cosInAngle=cos(curr->getInAngle()*deg2rad); + double cosOutAngle=cos(curr->getInAngle()*deg2rad); + curr->setInWeight(hPrev != 0 ? one_third*hPrev/cosInAngle : 1); + curr->setOutWeight(hNext != 0 ? one_third*hNext/cosOutAngle : 1); + }else{ + curr->setInWeight(1); + curr->setOutWeight(1); + } + } + } + +} + +void keyUpdated(animlib::AnimCurve* curve,int key){ + + int numKeys=curve->getNumKeys(); + // key position changes affect spline tangents of neighbors, so do two in each direction to be safe! + if(numKeys==1){ + + }else{ + int keyStart=std::max(0,key-1); + int keyEnd=std::min(numKeys,key+2); + keysUpdated(curve,keyStart,keyEnd,false); + } +} + + +void +CETool::setSelectedSegment(double frame,double val, + double inAngle,double outAngle, + double inWeight,double outWeight, + animlib::AnimKeyframe::tangentType inType, + animlib::AnimKeyframe::tangentType outType +) +{ + // TODO: fix + int curve; + int seg; + getSelectedSegment(curve, seg); + setSegment(curve,seg,frame,val,inAngle,outAngle,inWeight,outWeight,inType,outType); +} + + +void +CETool::setSegment(int curve,int seg,double frame,double val, + double inAngle,double outAngle, + double inWeight,double outWeight, + animlib::AnimKeyframe::tangentType inType, + animlib::AnimKeyframe::tangentType outType +) +{ + if(animlib::AnimKeyframe* key=(*_curves[curve]->animCurve)[seg]){ + _curves[curve]->animCurve->setTime(seg,frame); + key->setValue(val); + key->setInAngle(inAngle); + key->setOutAngle(outAngle); + key->setInWeight(inWeight); + key->setOutWeight(outWeight); + key->setInTangentType(inType); + key->setOutTangentType(outType); + keyUpdated(_curves[curve]->animCurve,seg); + emit(curveChanged(curve)); + } +} + + +/*Operate on a specified Segment */ +void +CETool::setSegmentFrame(double frame, int curve, int seg) +{ + // prevent making key cross other keys + animlib::AnimCurve& anim=*_curves[curve]->animCurve; + animlib::AnimKeyframe *prev=anim[seg-1],*curr=anim[seg],*next=anim[seg+1]; + // TODO: next ulp? + if(prev && prev->getTime()>=frame) frame=prev->getTime()+.001; + if(next && frame>=next->getTime()) frame=next->getTime()-.001; + //curr->setTime(frame); + _curves[curve]->animCurve->setTime(seg,frame); + keyUpdated(_curves[curve]->animCurve,seg); + emit curveChanged(curve); +} + + +void +CETool::setSegmentValue(double value, int curve, int seg) +{ + (_curves[curve]->animCurve->getFirstKey()+seg)->setValue(value); + keyUpdated(_curves[curve]->animCurve,seg); + emit curveChanged(curve); +} + +void +CETool::setSelectedWeighted(bool val) +{ + int curve,seg; + if(getSelectedCurve(curve) == errSUCCESS) + setWeighted(curve,val); +} + +void +CETool::setWeighted(int curve, bool val) +{ + auto animCurve=_curves[curve]->animCurve; + // now set all curves there had weights to 1. + // if the curve changes from weighted to non, we set all weights to 1 + // if the curve changes from non-weighted to weighted, we set all weights to equivalent values to not change curve + _curves[curve]->animCurve->setWeighted(val); + keysUpdated(_curves[curve]->animCurve,0,_curves[curve]->animCurve->getNumKeys(),true); + emit curveChanged(curve); +} + +void +CETool::setSelectedLocked(bool val) +{ + int curve,seg; + if(getSelectedSegment(curve,seg) == errSUCCESS) + setLocked(curve,seg,val); +} + +void +CETool::setLocked(int curve, int segment, bool val) +{ + auto animCurve=_curves[curve]->animCurve; + // now set all curves there had weights to 1. + // if the curve changes from weighted to non, we set all weights to 1 + // if the curve changes from non-weighted to weighted, we set all weights to equivalent values to not change curve + if(animlib::AnimKeyframe* key=(*_curves[curve]->animCurve)[segment]){ + + key->setLocked(val); + key->setInAngle(key->getOutAngle()); + key->setInTangentType(key->getOutTangentType()); + key->setInWeight(key->getOutWeight()); + keyUpdated(_curves[curve]->animCurve,segment); + emit curveChanged(curve); + } +} + + + +err::Result +CETool::setSegmentType(msg::cstr type, msg::list params) +{ + // TODO: fix +#if 0 + int curve; + int seg; + ECHK(getSelectedSegment(curve, seg)); + return _curves[curve]->expr.setSegmentType(seg, type, params); +#endif + return errSUCCESS; +} + +void +CETool::setKeyIn(int curve,int seg,double ang,double weight) +{ + animlib::AnimKeyframe& key=*(_curves[curve]->animCurve->getFirstKey()+seg); + bool weighted=_curves[curve]->animCurve->isWeighted(); + key.setInAngle(ang); + key.setInWeight(weighted?weight:1); + emit curveChanged(curve); +} + +void +CETool::setKeyOut(int curve,int seg,double ang,double weight) +{ + animlib::AnimKeyframe& key=*(_curves[curve]->animCurve->getFirstKey()+seg); + bool weighted=_curves[curve]->animCurve->isWeighted(); + key.setOutAngle(ang); + key.setOutWeight(weighted?weight:1); + emit curveChanged(curve); +} + +void +CETool::setSelectedInfinity(animlib::AnimCurve::infinityType preType,animlib::AnimCurve::infinityType postType) +{ + int curve; + int seg; + getSelectedSegment(curve, seg); + setInfinity(curve,preType,postType); +} + +void +CETool::setInfinity(int curveIndex,animlib::AnimCurve::infinityType preType,animlib::AnimCurve::infinityType postType) +{ + animlib::AnimCurve& curve=*_curves[curveIndex]->animCurve; + curve.setPreInfinity(preType); + curve.setPostInfinity(postType); + emit curveChanged(curveIndex); +} + +err::Result +CETool::changeSegmentType(msg::cstr newtype) +{ + // TODO: fix +#if 0 + int curve; + ECHK(getSelectedCurve(curve)); + CurveData* cdata = _curves[curve]; + std::set::iterator iter, end; + for (iter = cdata->segsSelected.begin(), end = cdata->segsSelected.end(); + iter != end; iter++) + { + if (*iter == 0) continue; // skip seg 0 + ECHK(cdata->expr.changeSegmentType(*iter, newtype)); + } + return errSUCCESS; +#endif + return errSUCCESS; +} + +void +CETool::deleteSegments() +{ + bool changed = 0; + for (int i = 0; i < numCurves(); i++) { + CurveData* curve = _curves[i]; + std::set::reverse_iterator seg; + // must delete segments in reverse to preserve indices + for (seg = curve->segsSelected.rbegin(); + seg != curve->segsSelected.rend(); + seg++) + { + curve->animCurve->removeKey(curve->animCurve->getFirstKey()+*seg); + } + if (!curve->segsSelected.empty()) { + curve->segsSelected.clear(); + changed = 1; + emit curveChanged(i); + } + + } + + if (changed) { + _selListValid = 0; + emit selectionChanged(); + } +} + + +err::Result +CETool::pan(double x, double y) +{ + if (x == 0 && y == 0) return errSUCCESS; + _vx += x; + _vy += y; + emit viewChanged(); + return errSUCCESS; +} + + +err::Result +CETool::zoom(double zoomX, double zoomY) +{ + return zoomAroundPoint(zoomX, zoomY, _vx, _vy); +} + + +err::Result +CETool::zoomAroundPoint(double zoomX, double zoomY, double x, double y) +{ + if (zoomX <= 0 || zoomY <= 0) return errINVPARM; + if (zoomX == 1 && zoomY == 1) return errSUCCESS; + double sx = 1/zoomX; + double sy = 1/zoomY; + + return setView(x + (_vx - x) * sx, + y + (_vy - y) * sy, + _vw * sx, + _vh * sy); +} + + +err::Result +CETool::setView(double x, double y, double w, double h) +{ + w = clamp(w, 1e-3, 1e5); + h = clamp(h, 1e-3, 1e5); + x = clamp(x, -1e5, 1e5); + y = clamp(y, -1e5, 1e5); + + if (x != _vx || y != _vy || w != _vw || h != _vh) { + _vx = x; + _vy = y; + _vw = w; + _vh = h; + emit viewChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::setCurveOffset(int curveIndex, double yPan, double yZoom) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + CurveData* curve = _curves[curveIndex]; + if (curve->ypan != yPan || + curve->yzoom != yZoom) + { + curve->ypan = yPan; + curve->yzoom = yZoom; + emit viewChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::frameSelection() +{ +// TODO: fix + // if no curves, do nothing + if (!numCurves()) return errSUCCESS; + + // get current view and adjust + double x=_vx, y=_vy, w=_vw, h=_vh; + + // if we have no selection, then frame all + bool frameAll = 1; + int i; + for (i = 0; i < numCurves(); i++) { + CurveData* curve = _curves[i]; + if (curve->selected) { frameAll = 0; break; } + } + + // find min/max time + bool initX=0; + double minX=std::numeric_limits::max(), + maxX=-std::numeric_limits::max(); // TODO: should be lowest in c++11 + + for (i = 0; i < numCurves(); i++) { + CurveData* curve = _curves[i]; + if (curve->numSegs<=1) continue; + // find first/last selected seg + int firstSeg = 1; + int lastSeg = curve->numSegs-1; + if (!frameAll) { + if (!curve->selected) continue; + if (curve->segsSelected.size()) { + firstSeg = *curve->segsSelected.begin(); + lastSeg = *curve->segsSelected.rbegin()+1; + if (lastSeg >= curve->numSegs) lastSeg = curve->numSegs-1; + if (firstSeg < 1) firstSeg = 1; + } + } + double min=curve->animCurve->getFirstKey()->getTime(); + double max=(curve->animCurve->getFirstKey()+curve->animCurve->getNumKeys()-1)->getTime(); + + + minX=std::min(minX,min); + maxX=std::max(maxX,max); + } + + // adjust horizontal view + if (numCurves()) { + x = (maxX+minX)/2; + if (maxX > minX) + w = (maxX-minX)*1.1; // add 10% margin + } + else { + minX = x-w/2; + maxX = x+w/2; + } + + // find min/max value over min/max time range + bool initY=false; + double minY=std::numeric_limits::max(), + maxY=-std::numeric_limits::max();// TODO: should be lowest in c++11 + + bool gotData=false; + for (i = 0; i < numCurves(); i++) { + CurveData* curve = _curves[i]; + if (!frameAll && !curve->selected) continue; + // TODO: this is not the correct bouds in the presence of oscillation + for(int i=0;i<(int)curve->animCurve->getNumKeys();i++){ + gotData=true; + double val=(curve->animCurve->getFirstKey()+i)->getValue(); + maxY=std::max(maxY,val); + minY=std::min(minY,val); + } + } + + // adjust vertical view + if (gotData) { + y = (maxY+minY)/2; + if (maxY > minY) + h = (maxY-minY)*1.1; + } + + // update to new view + setView(x,y,w,h); + + return errSUCCESS; +} + +err::Result +CETool::getView(double& x, double& y, double& w, double& h) +{ + x = _vx; + y = _vy; + w = _vw; + h = _vh; + return errSUCCESS; +} + + +err::Result +CETool::getCurveOffset(double& yPan, double& yZoom, int curveIndex) +{ + if (curveIndex < 0 || curveIndex >= numCurves()) + return errINDEX; + CurveData* curve = _curves[curveIndex]; + yPan = curve->ypan; + yZoom = curve->yzoom; + return errSUCCESS; +} + + +err::Result +CETool::setTimeMode(int mode) +{ + if (mode < 0 || mode > 2) + return errINVPARM; + if (_timeMode != mode) { + _timeMode = mode; + emit timeModeChanged(); + } + return errSUCCESS; +} + + +err::Result +CETool::getTimeMode(int& mode) +{ + mode = _timeMode; + return errSUCCESS; +} + + +err::Result +CETool::map(QWidget*& uiComponent, QWidget* parent) +{ + _ui = new CEMainUI(parent, this); + uiComponent = _ui; + return errSUCCESS; +} + + +err::Result +CETool::postUnmapNotify() +{ + _ui = 0; + return errSUCCESS; +} + +err::Result +CETool::postMapNotify() +{ + return errSUCCESS; +} + +int +CETool::findCurve(animlib::AnimCurve* curve) +{ + // TODO - do something more efficient than linear search + // could use dict, but must take care to keep indices current + for (int i = 0; i < numCurves(); i++) + if (_curves[i]->animCurve == curve) return i; + return -1; +} + +int +CETool::findCurve(const std::string& curveName) +{ + // TODO - do something more efficient than linear search + // could use dict, but must take care to keep indices current + for (int i = 0; i < numCurves(); i++) + if (_curves[i]->name==curveName) return i; + return -1; +} diff --git a/src/SeExprEditor/CE/CETool.h b/src/SeExprEditor/CE/CETool.h new file mode 100644 index 00000000..11dd63cd --- /dev/null +++ b/src/SeExprEditor/CE/CETool.h @@ -0,0 +1,199 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file CETool.h +* @brief Contains the declaration of class CETool. +*/ + +#ifndef CETool_h +#define CETool_h + +#include +#include +#include +//#include +//#include +//qt3 #include +#include + +#include +class QWidget; +class CEMainUI; + +//**************************************************************************** +/** + * @class CETool + * @brief Insert one-line brief description of class CETool here. + * + * Insert detailed description of class CETool definition here. + * + * @author brentb + * + * @version 1.0 brentb 11/20/2001: Initial version of class CETool. + * + */ + +class CETool : + public QObject +{ + Q_OBJECT + +public: + /// Constructor + CETool(); + + /// Destructor + virtual ~CETool(); + + typedef std::vector AnimCurveList; + + + /// from iCurveEditor + virtual err::Result newCurve(msg::cstr name); + virtual err::Result addCurve(animlib::AnimCurve* curve); + virtual err::Result removeCurve(int curveIndex); + virtual err::Result removeSelectedCurves(); + virtual err::Result removeAllCurves(); + virtual err::Result findCurve(int& curveIndex, msg::cstr name); + virtual err::Result getCurve(animlib::AnimCurve*& id, int curveIndex); + virtual err::Result getCurves(AnimCurveList& curves); + virtual err::Result getCurveNames(std::vector& names); + virtual err::Result clearSelection(); + virtual err::Result selectCurve(int curveIndex); + virtual err::Result selectAddCurve(int curveIndex); + virtual err::Result deselectCurve(int curveIndex); + virtual err::Result selectSegment(int curveIndex, int segIndex); + virtual err::Result selectAddSegment(int curveIndex, int segIndex); + virtual err::Result deselectSegment(int curveIndex, int segIndex); + virtual err::Result selectCurves(msg::list curveIndices); + virtual err::Result selectSegments(int curveIndex, msg::list segIndices); + virtual err::Result getSelection(msg::list& selections); + virtual err::Result getSelectedCurve(int& curve); + virtual err::Result getSelectedSegment(int& curve, int& seg); + virtual err::Result isSegmentSelected(bool& selected, + int curveIndex, int segIndex); + int insertKey(double frame); + void setKeyIn(int curve,int seg,double ang,double weight); + void setKeyOut(int curve,int seg,double ang,double weight); + void setSelectedInfinity(animlib::AnimCurve::infinityType preType,animlib::AnimCurve::infinityType postType); + void setInfinity(int curve,animlib::AnimCurve::infinityType preType,animlib::AnimCurve::infinityType postType); + void setSelectedSegmentFrame(double frame); + void setSelectedSegmentValue(double value); + void setSegmentFrame(double frame, int curve, int segment); + void setSegmentValue(double value, int curve, int segment); + void setWeighted(int curve,bool val); + void setSelectedWeighted(bool val); + void setLocked(int curve,int segment,bool val); + void setSelectedLocked(bool val); + + void setSegmentStr(msg::cstr str); + void setSelectedSegment(double frame,double value, + double inAngle,double outAngle,double inWeight,double outWeight, + animlib::AnimKeyframe::tangentType inType, + animlib::AnimKeyframe::tangentType outType); + + void setSegment(int curve,int segment,double frame,double value, + double inAngle,double outAngle,double inWeight,double outWeight, + animlib::AnimKeyframe::tangentType inType, + animlib::AnimKeyframe::tangentType outType); + + void deleteSegments(); + + virtual err::Result setSegmentType(msg::cstr type, msg::list params); + virtual err::Result changeSegmentType(msg::cstr newtype); + virtual err::Result pan(double x, double y); + virtual err::Result zoom(double zoomX, double zoomY); + virtual err::Result zoomAroundPoint(double zoomX, double zoomY, + double x, double y); + virtual err::Result setView(double x, double y, double w, double h); + virtual err::Result setCurveOffset(int curveIndex, + double yPan, double yZoom); + virtual err::Result frameSelection(); + virtual err::Result getView(double& x, double& y, double& w, double& h); + virtual err::Result getCurveOffset(double& yPan, double& yZoom, + int curveIndex); + virtual err::Result setTimeMode(int mode); + virtual err::Result getTimeMode(int& mode); + + /// from iTool + /// applies any configuration changes to the tool + err::Result configureTool() { return errSUCCESS; } + /// saves any configuration changes to the tool + err::Result saveToolConfiguration() { return errSUCCESS; } + /// the tool should map the GUI and return the associated QWidget + err::Result map(QWidget*& uiComponent, QWidget* parent); + // called after the gui for the tool has been mapped + err::Result postMapNotify(); + /// called after the gui for the tool has been unmapped + err::Result postUnmapNotify(); + + /// public methods + int numCurves() const { return (int) _curves.size(); } + + CEMainUI* ui(){return _ui;} + +signals: + void curveChanged(int index); + void segChanged(int curve, int segment); + void curveListChanged(); + void selectionChanged(); + void viewChanged(); + void timeModeChanged(); + +private: + /// No definition by design, this is so accidental copying is prevented. + CETool ( const CETool& ); + /// No definition by design, this is so accidental assignment is prevented. + CETool& operator=( const CETool& ); + + /// Called by msg code when tool is unregistered + virtual void release() { delete this; } + + void addCurveInternal(animlib::AnimCurve* id, const char* name); + int findCurve(animlib::AnimCurve* curve); + int findCurve(const std::string& curveName); + + class CurveData; + msg::RcvrId _rcvrid; + CEMainUI* _ui; + double _vx, _vy, _vw, _vh; // view rectangle + int _timeMode; + + // per-curve data in curve list + struct CurveData { + animlib::AnimCurve* animCurve; + std::string name; + double ypan; + double yzoom; + bool selected; + int numSegs; + std::set segsSelected; + + ~CurveData() + { + delete animCurve; + } + }; + typedef std::vector CurveList; + CurveList _curves; + int _selectedCurve; + + // selection list cache + msg::list _selList; + bool _selListValid; +}; + +#endif //CETool_h diff --git a/src/SeExprEditor/CE/crap.cpp b/src/SeExprEditor/CE/crap.cpp new file mode 100644 index 00000000..41b92eb1 --- /dev/null +++ b/src/SeExprEditor/CE/crap.cpp @@ -0,0 +1,32 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include + +struct Foo{ + int a,b; + float getSum(){ + return a+b; + } +} + +int foo() +{ + Foo foo; + auto it=3+4; + + foo.getSum(); +} diff --git a/src/SeExprEditor/CE/test.cpp b/src/SeExprEditor/CE/test.cpp new file mode 100644 index 00000000..41cb56cc --- /dev/null +++ b/src/SeExprEditor/CE/test.cpp @@ -0,0 +1,67 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include +#include +#include "CETool.h" +#include "CEMainUI.h" + + +#include + +int main(int argc,char *argv[]) +{ + fp(); + QApplication app(argc,argv); + CETool* tool=new CETool(); + //tool->ui()->show(); + animlib::AnimCurve& anim=*new animlib::AnimCurve((animlib::AnimAttrID())); + anim.setPreInfinity(animlib::AnimCurve::kInfinityOscillate); + typedef animlib:: AnimKeyframe Key; + Key key1(0.,0.); + Key key2(2.,2.); + Key key3(4.,0.); + Key key4(5.,-2.); + key1.setInTangentType(animlib::AnimKeyframe::kTangentFixed); + key1.setInAngle(30); + key1.setOutTangentType(animlib::AnimKeyframe::kTangentFixed); + key1.setOutAngle(30); + anim.addKey(key1); + + key2.setInTangentType(animlib::AnimKeyframe::kTangentFixed); + key2.setInAngle(-50); + key2.setOutTangentType(animlib::AnimKeyframe::kTangentFixed); + key2.setOutAngle(-50); + anim.addKey(key2); + + key3.setInTangentType(animlib::AnimKeyframe::kTangentFixed); + key3.setOutTangentType(animlib::AnimKeyframe::kTangentFixed); + anim.addKey(key3); + key4.setInTangentType(animlib::AnimKeyframe::kTangentFixed); + key4.setOutTangentType(animlib::AnimKeyframe::kTangentFixed); + anim.addKey(key4); + + anim.setWeighted(true); + QWidget* widg; + tool->map(widg,0); + tool->addCurve(&anim); + widg->setMinimumWidth(512); + widg->show(); + //tool->disableControls(); + app.exec(); + return 0; +} + diff --git a/src/SeExprEditor/CMakeLists.txt b/src/SeExprEditor/CMakeLists.txt new file mode 100644 index 00000000..d10f9426 --- /dev/null +++ b/src/SeExprEditor/CMakeLists.txt @@ -0,0 +1,54 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + +find_package(Qt4 COMPONENTS QtCore QtGui QtOpenGL) # find and setup Qt4 for this project +if(QT4_FOUND) + + BuildParserScanner(SeExprSpecParserLex SeExprSpecParser SeExprSpec editor_parser_cpp) + set(SeExprEd_MOC_HDRS SeExprEdBrowser.h SeExprEdColorCurve.h SeExprEdControlCollection.h + SeExprEdControl.h SeExprEdCurve.h SeExprEdDialog.h SeExprEditor.h SeExprEdFileDialog.h SeExprEdGrapher2d.h + SeExprEdPopupDocumentation.h SeExprEdShortEdit.h) + set(SeExprEd_CPPS SeExprEdFileDialog.cpp SeExprEdControl.cpp SeExprEditor.cpp SeExpressionEditor.cpp + SeExprEdShortEdit.cpp SeExprEdCurve.cpp SeExprEdColorCurve.cpp SeExprEdEditableExpression.cpp + SeExprEdPopupDocumentation.cpp SeExprEdCompletionModel.cpp SeExprEdDialog.cpp SeExprEdControlCollection.cpp + SeExprEdGrapher2d.cpp SeExprEdBrowser.cpp SeExprEdExpression.cpp) + + qt4_wrap_cpp(SeExprEd_MOC_SRCS ${SeExprEd_MOC_HDRS}) + + add_library(SeExprEditor SHARED ${SeExprEd_CPPS} ${SeExprEd_MOC_SRCS} ${editor_parser_cpp}) +IF(WIN32) + add_library(SeExprEditor ${SeExprEd_CPPS} ${SeExprEd_MOC_SRCS} ${editor_parser_cpp}) + GENERATE_EXPORT_HEADER( SeExprEditor + BASE_NAME SeExprEditor + EXPORT_MACRO_NAME SeExprEditor + EXPORT_FILE_NAME SeExprEditor_Export.h + STATIC_DEFINE SeExprEditor_BUILT_AS_STATIC + ) +ENDIF(WIN32) + + + install(TARGETS SeExprEditor DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SeExprEd_MOC_HDRS} DESTINATION include/SeExprEditor) + include_directories(${QT_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries(SeExprEditor ${QT_QTCORE_LIBRARY}) + target_link_libraries(SeExprEditor ${QT_QTGUI_LIBRARY}) + target_link_libraries(SeExprEditor ${QT_QTOPENGL_LIBRARY}) + target_link_libraries(SeExprEditor ${QT_QTOPENGL_LIBRARY}) +IF(WIN32) + target_link_libraries(SeExprEditor opengl32) +ENDIF(WIN32) + target_link_libraries(SeExprEditor ${SEEXPR_LIBRARIES}) +endif(QT4_FOUND) diff --git a/src/SeExprEditor/SeExprEdBrowser.cpp b/src/SeExprEditor/SeExprEdBrowser.cpp new file mode 100644 index 00000000..deb4e636 --- /dev/null +++ b/src/SeExprEditor/SeExprEdBrowser.cpp @@ -0,0 +1,573 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdExpression.h +* @brief A basic expression context for the expression previewer +* @author aselle +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "SeExprEditor.h" +#include "SeExprEdBrowser.h" + +#define P3D_CONFIG_ENVVAR "P3D_CONFIG_PATH" + + +class SeExprEdTreeItem +{ +public: + SeExprEdTreeItem(SeExprEdTreeItem* parent,const QString& label,const QString& path) + :row(-1),parent(parent),label(label),path(path),populated(parent==0) + {} + + ~SeExprEdTreeItem() + { + for(unsigned int i=0;ipath==path) return this; + else{ + populate(); + for(unsigned int i=0;ifind(path); + if(ret) return ret; + } + } + return 0; + } + + void clear() + { + for(unsigned int i=0;i::ConstIterator it=infos.constBegin();it!=infos.constEnd();++it){ + const QFileInfo* fi=&*it; + if(fi->isDir() || fi->fileName().endsWith(".se")){ + addChild(new SeExprEdTreeItem(this,fi->fileName(),fi->filePath())); + } + } + } + } + + void addChild(SeExprEdTreeItem* child) + { + child->row=children.size(); + children.push_back(child); + } + + SeExprEdTreeItem* getChild(const int row) + { + populate(); + if(row<0 || row>(int)children.size()){ + assert(false); + } + return children[row]; + } + + int getChildCount() + { + populate(); + return children.size(); + } + + void regen() + { + std::vector labels,paths; + for(unsigned int i=0;ilabel); + paths.push_back(children[i]->path); + delete children[i]; + } + children.clear(); + + for(unsigned int i=0;i children; + bool populated; +}; + +class SeExprEdTreeModel:public QAbstractItemModel +{ + SeExprEdTreeItem* root; +public: + SeExprEdTreeModel() + :root(new SeExprEdTreeItem(0,"","")) + {} + + ~SeExprEdTreeModel() + { + delete root; + } + + void update() + { + reset(); + } + + void clear() + { + root->clear(); + update(); + } + + void addPath(const char* label,const char* path) + { + root->addChild(new SeExprEdTreeItem(root,label,path)); + } + + QModelIndex parent(const QModelIndex& index) const + { + if(!index.isValid()) return QModelIndex(); + SeExprEdTreeItem* item=(SeExprEdTreeItem*)(index.internalPointer()); + SeExprEdTreeItem* parentItem=item->parent; + if(parentItem==root) return QModelIndex(); + else return createIndex(parentItem->row,0,parentItem); + } + + QModelIndex index(int row,int column,const QModelIndex& parent=QModelIndex()) const + { + if(!hasIndex(row,column,parent)) + return QModelIndex(); + else if(!parent.isValid()) return createIndex(row,column,root->getChild(row)); + else{ + SeExprEdTreeItem* item=(SeExprEdTreeItem*)(parent.internalPointer()); + return createIndex(row,column,item->getChild(row)); + } + } + + int columnCount(const QModelIndex& parent) const + {Q_UNUSED(parent); return 1;} + + int rowCount(const QModelIndex& parent=QModelIndex()) const + { + if(!parent.isValid()) return root->getChildCount(); + else{ + SeExprEdTreeItem* item=(SeExprEdTreeItem*)(parent.internalPointer()); + if(!item) return root->getChildCount(); + else return item->getChildCount(); + } + } + + QVariant data(const QModelIndex& index,int role=Qt::DisplayRole) const + { + if(!index.isValid()) return QVariant(); + if(role!=Qt::DisplayRole) return QVariant(); + SeExprEdTreeItem* item=(SeExprEdTreeItem*)(index.internalPointer()); + if(!item) return QVariant(); + else return QVariant(item->label); + } + + QModelIndex find(QString path) + { + SeExprEdTreeItem* item=root->find(path); + if(!item) { + root->regen(); + reset(); + item=root->find(path); + } + if(item){ + std::cerr<<"found it "<row,0,item); + } + + return QModelIndex(); + } + +}; + +class SeExprEdTreeFilterModel:public QSortFilterProxyModel +{ +public: + SeExprEdTreeFilterModel(QWidget* parent=0) + :QSortFilterProxyModel(parent) + {} + + void update() + { + reset(); + } + + bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const + { + if(sourceParent.isValid() && + sourceModel()->data(sourceParent).toString().contains(filterRegExp())) return true; + QString data=sourceModel()->data(sourceModel()->index(sourceRow,0,sourceParent)).toString(); + bool keep=data.contains(filterRegExp()); + + QModelIndex subIndex=sourceModel()->index(sourceRow,0,sourceParent); + if(subIndex.isValid()){ + for(int i=0;irowCount(subIndex);++i) + keep = keep || filterAcceptsRow(i, subIndex); + } + return keep; + } + +}; + +SeExprEdBrowser::~SeExprEdBrowser() +{ + delete treeModel; +} + +SeExprEdBrowser::SeExprEdBrowser(QWidget* parent, SeExprEditor* editor) + :QWidget(parent),editor(editor), + _context(""), + _searchPath("") +{ + QVBoxLayout* rootLayout = new QVBoxLayout; + rootLayout->setMargin(0); + this->setLayout(rootLayout); + // search and clear widgets + QHBoxLayout* searchAndClearLayout=new QHBoxLayout(); + exprFilter=new QLineEdit(); + connect(exprFilter,SIGNAL(textChanged(const QString&)),SLOT(filterChanged(const QString&))); + searchAndClearLayout->addWidget(exprFilter,2); + QPushButton* clearFilterButton=new QPushButton("X"); + clearFilterButton->setFixedWidth(24); + searchAndClearLayout->addWidget(clearFilterButton,1); + rootLayout->addLayout(searchAndClearLayout); + connect(clearFilterButton,SIGNAL(clicked()),SLOT(clearFilter())); + // model of tree + treeModel=new SeExprEdTreeModel(); + proxyModel=new SeExprEdTreeFilterModel(this); + proxyModel->setSourceModel(treeModel); + // tree widget + treeNew=new QTreeView; + treeNew->setModel(proxyModel); + treeNew->hideColumn(1); + treeNew->setHeaderHidden(true); + rootLayout->addWidget(treeNew); + // selection mode and signal + treeNew->setSelectionMode(QAbstractItemView::SingleSelection); + connect(treeNew->selectionModel(),SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)),SLOT(handleSelection(const QModelIndex&,const QModelIndex&))); +} + +void SeExprEdBrowser::addPath(const std::string& name,const std::string& path) +{ + labels.append(QString::fromStdString(name)); + paths.append(QString::fromStdString(path)); + treeModel->addPath(name.c_str(),path.c_str()); +} + +void SeExprEdBrowser::setSearchPath(const QString& context, const QString& path) +{ + _context = context.toStdString(); + _searchPath = path.toStdString(); +} + +std::string SeExprEdBrowser::getSelectedPath() +{ + QModelIndex sel=treeNew->currentIndex(); + if(sel.isValid()){ + QModelIndex realCurrent=proxyModel->mapToSource(sel); + SeExprEdTreeItem* item=(SeExprEdTreeItem*)realCurrent.internalPointer(); + return item->path.toStdString(); + } + return std::string(""); +} + +void SeExprEdBrowser::selectPath(const char * path) +{ + QModelIndex index=treeModel->find(path); + treeNew->setCurrentIndex(proxyModel->mapFromSource(index)); +} + +void SeExprEdBrowser::update() +{ + treeModel->update(); + proxyModel->update(); +} + +void SeExprEdBrowser::handleSelection(const QModelIndex& current,const QModelIndex& previous) +{ + Q_UNUSED(previous) + if(current.isValid()){ + QModelIndex realCurrent=proxyModel->mapToSource(current); + SeExprEdTreeItem* item=(SeExprEdTreeItem*)realCurrent.internalPointer(); + QString path=item->path; + if(path.endsWith(".se")){ + std::ifstream file(path.toStdString().c_str()); + std::string fileContents((std::istreambuf_iterator(file)),std::istreambuf_iterator()); + editor->setExpr(fileContents,true); + } + } +} + +void SeExprEdBrowser::clear() +{ + labels.clear(); + paths.clear(); + clearSelection(); + + treeModel->clear(); +} + + +void SeExprEdBrowser::clearSelection() +{ + treeNew->clearSelection(); +} + +void SeExprEdBrowser::clearFilter() +{ + exprFilter->clear(); +} + +void SeExprEdBrowser::filterChanged(const QString& str) +{ + proxyModel->setFilterRegExp(QRegExp(str)); + proxyModel->setFilterKeyColumn(0); + if(str!=""){ + treeNew->expandAll(); + }else{ + treeNew->collapseAll(); + } +} + +void SeExprEdBrowser::saveExpressionAs() +{ + QString path = QFileDialog::getSaveFileName( + this, "Save Expression", QString::fromStdString(_userExprDir), + "*.se"); + + if (path.length() > 0) { + std::ofstream file(path.toStdString().c_str()); + if (!file) { + QString msg = QString("Could not open file %1 for writing").arg(path); + QMessageBox::warning(this, "Error", + QString("%1") + .arg(msg)); + return; + } + file << editor->getExpr(); + file.close(); + + update(); + selectPath(path.toStdString().c_str()); + } +} + +void SeExprEdBrowser::saveLocalExpressionAs() +{ + QString path = QFileDialog::getSaveFileName( + this, "Save Expression", QString::fromStdString(_localExprDir), + "*.se"); + + if (path.length() > 0) { + std::ofstream file(path.toStdString().c_str()); + if (!file) { + QString msg = QString("Could not open file %1 for writing").arg(path); + QMessageBox::warning(this, "Error", + QString("%1") + .arg(msg)); + return; + } + file << editor->getExpr(); + file.close(); + + update(); + selectPath(path.toStdString().c_str()); + } +} + + +void SeExprEdBrowser::saveExpression() +{ + std::string path = getSelectedPath(); + if (path.length() == 0) { + saveExpressionAs(); + return; + } + std::ofstream file(path.c_str()); + if (!file) { + QString msg = QString("Could not open file %1 for writing. Is it read-only?").arg(QString::fromStdString(path)); + QMessageBox::warning(this, "Error", + QString("%1") + .arg(msg)); + return; + } + file << editor->getExpr(); + file.close(); +} + +void SeExprEdBrowser::expandAll() +{ + treeNew->expandAll(); +} + +// Location for storing user's expression files +void SeExprEdBrowser::addUserExpressionPath(const std::string &context) +{ + char* homepath = getenv("HOME"); + if(homepath){ + std::string path= std::string(homepath) + "/" + context + "/expressions/"; + if(QDir(QString(path.c_str())).exists()){ + _userExprDir=path; + addPath("My Expressions",path); + } + } +} + +/* + * NOTE: The hard-coded paint3d assumptions can be removed once + * it (and bonsai?) are adjusted to call setSearchPath(context, path) + */ + +bool SeExprEdBrowser::getExpressionDirs() +{ + const char *env; + bool enableLocal = false; + /*bool homeFound = false; -- for xgen's config.txt UserRepo section below */ + + if (_searchPath.length() > 0) + env = _searchPath.c_str(); + else + env = getenv(P3D_CONFIG_ENVVAR); /* For backwards compatibility */ + + if (!env) + return enableLocal; + + std::string context; + if (_context.length() > 0) { + context = _context; + } else { + context = "paint3d"; /* For backwards compatibility */ + } + + clear(); + + std::string configFile=std::string(env)+"/config.txt"; + std::ifstream file(configFile.c_str()); + if(file){ + + std::string key; + while(file){ + file>>key; + + if(key[0]=='#'){ + char buffer[1024]; + file.getline(buffer,1024); + } else { + if (key=="ExpressionDir"){ + std::string label,path; + file>>label; + file>>path; + if(QDir(QString(path.c_str())).exists()) + addPath(label,path); + } else if (key=="ExpressionSubDir"){ + std::string path; + file>>path; + _localExprDir=path; + if(QDir(QString(path.c_str())).exists()){ + addPath("Local",_localExprDir); + enableLocal=true; + } + /* These are for compatibility with xgen. + * Long-term, xgen should use the same format. + * Longer-term, we should use JSON or something */ + } else if (key == "GlobalRepo") { + std::string path; + file>>path; + path += "/expressions/"; + if(QDir(QString(path.c_str())).exists()) + addPath("Global", path); + } else if (key == "LocalRepo") { + std::string path; + file>>path; + path += "/expressions/"; + _localExprDir=path; + if(QDir(QString(path.c_str())).exists()){ + addPath("Local",_localExprDir); + enableLocal=true; + } + + /* + * xgen's config.txt has a "UserRepo" section but we + * intentionally ignore it since we already add the user dir + * down where the HOME stuff is handled + */ + + /* + } else if (key == "UserRepo") { + std::string path; + file>>path; + path += "/expressions/"; + + size_t found = path.find("${HOME}"); + + if (found != std::string::npos) { + char *homepath = getenv("HOME"); + if (homepath) { + path.replace(found, strlen("${HOME}"), homepath); + } else { + continue; + } + } + if(QDir(QString(path.c_str())).exists()){ + addPath("User", path); + homeFound = true; + } + */ + } else{ + char buffer[1024]; + file.getline(buffer,1024); + } + } + } + } + addUserExpressionPath(context); + update(); + return enableLocal; +} + diff --git a/src/SeExprEditor/SeExprEdBrowser.h b/src/SeExprEditor/SeExprEdBrowser.h new file mode 100644 index 00000000..e07f611e --- /dev/null +++ b/src/SeExprEditor/SeExprEdBrowser.h @@ -0,0 +1,85 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdBrowser.h +* @brief Browser for a library of expressions from a tree of files +* @author aselle +*/ +#ifndef SeExprEdBrowser_h +#define SeExprEdBrowser_h + + +#include +#include + +#include +#include +#include + +class QLineEdit; +class QTreeWidget; +class QTreeView; +class QTreeWidgetItem; +class QTextBrowser; +class SeExprEditor; +class QSortFilterProxyModel; +class QDir; + +class SeExprEdTreeModel; +class SeExprEdTreeFilterModel; + +class SeExprEdBrowser : public QWidget +{ + Q_OBJECT + + SeExprEditor* editor; + QList labels; + QList paths; + SeExprEdTreeModel* treeModel; + SeExprEdTreeFilterModel* proxyModel; + QTreeView* treeNew; + QLineEdit* exprFilter; + std::string _userExprDir; + std::string _localExprDir; + std::string _context; + std::string _searchPath; + +public: + SeExprEdBrowser(QWidget* parent, SeExprEditor* editor); + ~SeExprEdBrowser(); + void addPath(const std::string& name,const std::string& path); + std::string getSelectedPath(); + void selectPath(const char * path); + void addUserExpressionPath(const std::string &context); + bool getExpressionDirs(); + bool getExpressionDirs(const std::string& context); + void setSearchPath(const QString& context, const QString& path); + void expandAll(); +public slots: + void handleSelection(const QModelIndex& current,const QModelIndex& previous); + void update(); + void clear(); + void clearSelection(); + void saveExpression(); + void saveLocalExpressionAs(); + void saveExpressionAs(); +private slots: + void clearFilter(); + void filterChanged(const QString& str); + +}; + +#endif diff --git a/src/SeExprEditor/SeExprEdColorCurve.cpp b/src/SeExprEditor/SeExprEdColorCurve.cpp new file mode 100644 index 00000000..4d43135e --- /dev/null +++ b/src/SeExprEditor/SeExprEdColorCurve.cpp @@ -0,0 +1,566 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdColorCurve.cpp +* @brief Contains PyQt4 Ramp Widget to emulate Maya's ramp widget +* @author Arthur Shek +* @version ashek 05/04/09 Initial Version +*/ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef SEEXPR_USE_QDGUI +# include +#endif + +#include "SeExprEdColorCurve.h" + +CCurveScene::CCurveScene() : _curve(new T_CURVE),_width(320), _height(170), _color(SeVec3d(.5)), _interp(T_CURVE::kMonotoneSpline), + _selectedItem(-1), _pixmapDirty(true), _baseRectW(0), _baseRect(0), _lmb(false) +{ + rebuildCurve(); + resize(_width, _height); +} + +CCurveScene::~CCurveScene() +{ + delete _curve; +} + + +void CCurveScene::resize(const int width, const int height) +{ + // width and height already have the 8 px padding factored in + _width = width-16; + _height = height-16; + setSceneRect(-9, -2, width, height); + drawRect(); + drawPoints(); + _pixmap = QPixmap(_width, _height); + _pixmapDirty = true; +} + +void CCurveScene::rebuildCurve() +{ + delete _curve; + _curve=new T_CURVE; + for(unsigned int i=0;i<_cvs.size();i++) + _curve->addPoint(_cvs[i]._pos,_cvs[i]._val,_cvs[i]._interp); + _curve->preparePoints(); +} + +void CCurveScene::addPoint(double x, const SeVec3d y, const T_INTERP interp, const bool select) +{ + x=SeExpr::clamp(x,0,1); + + _cvs.push_back(T_CURVE::CV(x,y,T_INTERP(interp))); + int newIndex=_cvs.size()-1; + + rebuildCurve(); + + if(select){ + _selectedItem = newIndex; + emit cvSelected(x, y, interp); + } + _pixmapDirty = true; + _baseRectW->update(); + drawPoints(); +} + +void CCurveScene::removePoint(const int index) +{ + _cvs.erase(_cvs.begin()+index); + _selectedItem = -1; + rebuildCurve(); + + _pixmapDirty = true; + _baseRectW->update(); + drawPoints(); + emitCurveChanged(); +} + +void CCurveScene::removeAll() +{ + _cvs.clear(); +} + + +void CCurveScene::keyPressEvent(QKeyEvent *event) +{ + if (((event->key() == Qt::Key_Backspace) || + (event->key() == Qt::Key_Delete)) && (_selectedItem >= 0)) { + // user hit delete with cv selected + removePoint(_selectedItem); + } +} + +void CCurveScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + _lmb = true; + QPointF pos = mouseEvent->scenePos(); + // get items under mouse click + QList itemList = items(pos); + if (itemList.empty()) { + _selectedItem = -1; + emit cvSelected(-1, SeVec3d(0.0), _interp); + drawPoints(); + } else if (itemList[0]->zValue() == 2) { + // getting here means we've selected a current point + const int numCircle = _circleObjects.size(); + for (int i = 0; i < numCircle; i++ ) { + QGraphicsItem *obj = _circleObjects[i]; + if (obj == itemList[0]) { + _selectedItem = i; + _color = _cvs[i]._val; + _interp = _cvs[i]._interp; + emit cvSelected(_cvs[i]._pos, _cvs[i]._val, _cvs[i]._interp); + } + } + drawPoints(); + } else { + // getting here means we want to create a new point + double myx=pos.x()/_width; + T_INTERP interpFromNearby=_curve->getLowerBoundCV(SeExpr::clamp(myx,0,1))._interp; + if(interpFromNearby==T_CURVE::kNone) interpFromNearby=T_CURVE::kMonotoneSpline; + addPoint(pos.x()/_width, _color, interpFromNearby); + emitCurveChanged(); + } +} + +void CCurveScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + if (_lmb) { + QPointF point = mouseEvent->scenePos(); + if (_selectedItem >= 0) { + // clamp motion to inside curve area + double pos = SeExpr::clamp(point.x()/_width,0,1); + _cvs[_selectedItem]._pos=pos; + rebuildCurve(); + _pixmapDirty = true; + _baseRectW->update(); + emit cvSelected(pos, _cvs[_selectedItem]._val, _cvs[_selectedItem]._interp); + drawPoints(); + emitCurveChanged(); + } + } +} + +void CCurveScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + Q_UNUSED(mouseEvent); + _lmb = false; +} + +// user selected a different interpolation type, redraw +void CCurveScene::interpChanged(const int interp) +{ + _interp = (T_INTERP) interp; + if (_selectedItem >= 0) { + _cvs[_selectedItem]._interp = _interp; + rebuildCurve(); + _pixmapDirty = true; + _baseRectW->update(); + emitCurveChanged(); + } +} + +// user entered a different point position, redraw +void CCurveScene::selPosChanged(double pos) +{ + if (_selectedItem >= 0) { + pos=SeExpr::clamp(pos,0,1); + _cvs[_selectedItem]._pos = pos; + rebuildCurve(); + _pixmapDirty = true; + _baseRectW->update(); + drawPoints(); + emitCurveChanged(); + } +} + +// user entered a different point value, redraw +void CCurveScene::selValChanged(const SeVec3d& val) +{ + _color = val; + if (_selectedItem >= 0) { + _cvs[_selectedItem]._val = val; + rebuildCurve(); + _pixmapDirty = true; + _baseRectW->update(); + drawPoints(); + emitCurveChanged(); + } +} + + +// return points in reverse order in order to use same parsing in editor +void CCurveScene::emitCurveChanged() +{ + emit curveChanged(); +} + +QPixmap& CCurveScene::getPixmap() +{ + if (_pixmapDirty) { + QByteArray buf; + buf.append(QString("P6\n%1 %2\n255\n").arg(_width).arg(_height)); + buf.append(getCPixmap()); + _pixmap.loadFromData(buf, "PPM"); + _pixmapDirty = false; + } + return _pixmap; +} + + +QByteArray CCurveScene::getCPixmap() +{ + // create pixmap, set to gray + const int len = 3 * _width * _height; + QByteArray pixmap(len, 127); + + double paramInc = 1.0 / (_width - 2); + double param = 0.5 * paramInc; // start at pixel center + // add black lines to left + char* ptr = pixmap.data(); + *ptr++ = 0; + *ptr++ = 0; + *ptr++ = 0; + for (int i = 1; i < _width - 1; i++) { + SeVec3d color = _curve->getValue(param); + *ptr++ = char(std::min(std::max(0.0, 255 * color[0]), 255.0) + 0.5); + *ptr++ = char(std::min(std::max(0.0, 255 * color[1]), 255.0) + 0.5); + *ptr++ = char(std::min(std::max(0.0, 255 * color[2]), 255.0) + 0.5); + param += paramInc; + } + // add black lines to right + *ptr++ = 0; + *ptr++ = 0; + *ptr++ = 0; + + for (int i = 1; i < _height-1; i++) { + memcpy(pixmap.data()+(i * _width * 3), pixmap.data()+((i - 1) * _width * 3), _width * 3); + } + + // add black lines to top and bottom + memset(pixmap.data(), 0, _width * 3); + memset(pixmap.data()+((_height - 1) * _width * 3), 0, _width * 3); + + return pixmap; +} + + +// draws the base gray outline rectangle +void CCurveScene::drawRect() +{ + if (_baseRectW == 0) { + _baseRectW = new SeExprEdCBoxWidget(this); + } + if (_baseRect == 0) { + _baseRect = addWidget(_baseRectW); + } + _baseRect->widget()->setFixedSize(_width, _height); + _baseRect->widget()->update(); + _baseRect->setZValue(0); +} + + +// draws the cv points +void CCurveScene::drawPoints() +{ + while (_circleObjects.size()) { + delete _circleObjects[0]; + _circleObjects.erase(_circleObjects.begin()); + } + const int numCV = _cvs.size(); + for (int i = 0; i < numCV; i++) { + const T_CURVE::CV& pt = _cvs[i]; + QPen pen; + if (i == _selectedItem) { + pen = QPen(QColor(255,170,0),1.0); + } else { + pen = QPen(Qt::black,1.0); + } + _circleObjects.push_back(addEllipse(pt._pos*_width-4, _height+3, 8, 8, pen, QBrush(QColor(int(255 * pt._val[0] +0.5), int(255 * pt._val[1] + 0.5), int(255 * pt._val[2] + 0.5))))); + QGraphicsEllipseItem *circle = _circleObjects.back(); + circle->setFlag(QGraphicsItem::ItemIsMovable, true); + circle->setZValue(2); + } +} + + +void SeExprEdCBoxWidget::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + QPainter p(this); + p.drawPixmap(0, 0, _curveScene->getPixmap()); +} + +void SeExprEdCSwatchFrame::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + QPainter p(this); + p.fillRect(contentsRect(),_color); +} + + +SeExprEdCSwatchFrame::SeExprEdCSwatchFrame(SeVec3d value, QWidget* parent) : QFrame(parent), _value(value) +{ + _color = QColor(int(255 * _value[0] + 0.5), int(255 * _value[1] + 0.5), int(255 * _value[2] + 0.5)); +} + + +void SeExprEdCSwatchFrame::setValue(const SeVec3d &value) +{ + _color = QColor(int(255 * value[0] + 0.5), int(255 * value[1] + 0.5), int(255 * value[2] + 0.5)); + //setPalette(QPalette(_color)); + _value = value; + repaint(); +} + +SeVec3d SeExprEdCSwatchFrame::getValue() const +{ + return _value; +} + + +void SeExprEdCSwatchFrame::mousePressEvent(QMouseEvent* event) +{ + Q_UNUSED(event); +#ifdef SEEXPR_USE_QDGUI + QColor color = QdColorPickerDialog::chooseColorFromDialog(_color,this); +#else + QColor color = QColorDialog::getColor(_color); +#endif + if (color.isValid()) { + _value[0] = color.red() / 255.0; + _value[1] = color.green() / 255.0; + _value[2] = color.blue() / 255.0; + setPalette(QPalette(color)); + _color = color; + emit selValChangedSignal(_value); + emit swatchChanged(color); + } +} + + +SeExprEdColorCurve::SeExprEdColorCurve(QWidget* parent, QString pLabel, QString vLabel, QString iLabel, + bool expandable) : + QWidget(parent), _scene(0), _selPosEdit(0), _selValEdit(0), _interpComboBox(0) +{ + Q_UNUSED(iLabel); + QHBoxLayout *mainLayout = new QHBoxLayout(); + mainLayout->setSpacing(2); + mainLayout->setMargin(5); + + QWidget *edits = new QWidget; + QVBoxLayout *editsLayout = new QVBoxLayout; + editsLayout->setAlignment(Qt::AlignTop); + editsLayout->setSpacing(0); + editsLayout->setMargin(0); + edits->setLayout(editsLayout); + + QWidget *selPos = new QWidget; + QHBoxLayout *selPosLayout = new QHBoxLayout; + selPosLayout->setSpacing(1); + selPosLayout->setMargin(1); + selPos->setLayout(selPosLayout); + _selPosEdit = new QLineEdit; + QDoubleValidator *posValidator = new QDoubleValidator(0.0,1.0,6,_selPosEdit); + _selPosEdit->setValidator(posValidator); + _selPosEdit->setFixedWidth(38); + _selPosEdit->setFixedHeight(20); + selPosLayout->addStretch(50); + QLabel *posLabel; + if (pLabel.isEmpty()) { + posLabel = new QLabel("Selected Position: "); + } else { + posLabel = new QLabel(pLabel); + } + selPosLayout->addWidget(posLabel); + selPosLayout->addWidget(_selPosEdit); + + QWidget *selVal = new QWidget; + QBoxLayout *selValLayout = new QHBoxLayout; + selValLayout->setSpacing(1); + selValLayout->setMargin(1); + selVal->setLayout(selValLayout); + _selValEdit = new SeExprEdCSwatchFrame(SeVec3d(.5)); + _selValEdit->setFixedWidth(38); + _selValEdit->setFixedHeight(20); + selValLayout->addStretch(50); + QLabel *valLabel; + if (vLabel.isEmpty()) { + valLabel = new QLabel("Selected Color: "); + } else { + valLabel = new QLabel(vLabel); + } + selValLayout->addWidget(valLabel); + selValLayout->addWidget(_selValEdit); + + _interpComboBox = new QComboBox; + _interpComboBox->addItem("None"); + _interpComboBox->addItem("Linear"); + _interpComboBox->addItem("Smooth"); + _interpComboBox->addItem("Spline"); + _interpComboBox->addItem("MSpline"); + _interpComboBox->setCurrentIndex(4); + _interpComboBox->setFixedWidth(70); + _interpComboBox->setFixedHeight(20); + + editsLayout->addWidget(selPos); + editsLayout->addWidget(selVal); + editsLayout->addWidget(_interpComboBox); + + QFrame *curveFrame = new QFrame; + curveFrame->setFrameShape(QFrame::Panel); + curveFrame->setFrameShadow(QFrame::Sunken); + curveFrame->setLineWidth(1); + QHBoxLayout *curveFrameLayout = new QHBoxLayout; + curveFrameLayout->setMargin(0); + CurveGraphicsView *curveView = new CurveGraphicsView; + curveView->setFrameShape(QFrame::Panel); + curveView->setFrameShadow(QFrame::Sunken); + curveView->setLineWidth(1); + curveView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + curveView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + _scene = new CCurveScene; + curveView->setScene(_scene); + curveView->setTransform(QTransform().scale(1, -1)); + curveView->setRenderHints(QPainter::Antialiasing); + curveFrameLayout->addWidget(curveView); + curveFrame->setLayout(curveFrameLayout); + + mainLayout->addWidget(edits); + mainLayout->addWidget(curveFrame); + if(expandable){ + QPushButton* expandButton=new QPushButton(">"); + expandButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding); + expandButton->setFixedWidth(15); + mainLayout->addWidget(expandButton); + // open a the detail widget when clicked + connect(expandButton, SIGNAL(clicked()), this, SLOT(openDetail())); + } + mainLayout->setStretchFactor(curveFrame,100); + setLayout(mainLayout); + + // SIGNALS + + // when a user selects a cv, update the fields on left + connect(_scene, SIGNAL(cvSelected(double, SeVec3d, T_INTERP)), this, SLOT(cvSelectedSlot(double, SeVec3d, T_INTERP))); + // when a user selects a different interp, the curve has to redraw + connect(_interpComboBox, SIGNAL(activated(int)), _scene, SLOT(interpChanged(int))); + // when a user types a different position, the curve has to redraw + connect(_selPosEdit, SIGNAL(returnPressed()), this, SLOT(selPosChanged())); + connect(this, SIGNAL(selPosChangedSignal(double)), _scene, SLOT(selPosChanged(double))); + // when a user selects a different color, the ramp has to redraw + connect(_selValEdit, SIGNAL(selValChangedSignal(SeVec3d)), _scene, SLOT(selValChanged(SeVec3d))); + connect(_selValEdit, SIGNAL(swatchChanged(QColor)), this, SLOT(internalSwatchChanged(QColor))); + // when the widget is resized, resize the curve widget + connect(curveView, SIGNAL(resizeSignal(int, int)), _scene, SLOT(resize(int, int))); +} + + +// CV selected, update the user interface fields. +void SeExprEdColorCurve::cvSelectedSlot(const double pos, const SeVec3d val, const T_INTERP interp) +{ + QString posStr; + if (pos >= 0.0) { + posStr.setNum(pos, 'f', 3); + _selPosEdit->setText(posStr); + _selValEdit->setValue(val); + emit swatchChanged(QColor::fromRgbF(val[0],val[1],val[2],1)); + _interpComboBox->setCurrentIndex(interp); + } +} + +// User entered new position, round and send signal to redraw curve. +void SeExprEdColorCurve::selPosChanged() +{ + double pos = SeExpr::clamp(QString(_selPosEdit->text()).toFloat(),0,1); + _selPosEdit->setText(QString("%1").arg(pos, 0, 'f', 3)); + emit selPosChangedSignal(pos); +} + +void SeExprEdColorCurve::addPoint(const double x, const SeVec3d y, const T_INTERP interp, const bool select) +{ + _scene->addPoint(x, y, interp, select); +} + +void SeExprEdColorCurve::setSwatchColor(QColor color) +{ + SeVec3d newColor(color.redF(),color.greenF(),color.blueF()); + _scene->selValChanged(newColor); + _selValEdit->setValue(newColor); +} + +QColor SeExprEdColorCurve::getSwatchColor() +{ + SeVec3d val=_selValEdit->getValue(); + return QColor::fromRgbF(val[0],val[1],val[2],1); +} + +void SeExprEdColorCurve::internalSwatchChanged(QColor color) +{ + emit swatchChanged(color); +} + +void SeExprEdColorCurve::openDetail() +{ + QDialog* dialog=new QDialog(); + dialog->setMinimumWidth(1024); + dialog->setMinimumHeight(400); + SeExprEdColorCurve* curve=new SeExprEdColorCurve(0,"","","",false); + + // copy points into new data + const std::vector& data=_scene->_cvs; + typedef std::vector::const_iterator ITERATOR; + for(ITERATOR i=data.begin();i!=data.end();++i) + curve->addPoint(i->_pos,i->_val,i->_interp); + + QVBoxLayout* layout=new QVBoxLayout(); + dialog->setLayout(layout); + layout->addWidget(curve); + + dialog->setLayout(layout); + layout->addWidget(curve); + QDialogButtonBox* buttonbar=new QDialogButtonBox(); + buttonbar->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + connect(buttonbar,SIGNAL(accepted()),dialog,SLOT(accept())); + connect(buttonbar,SIGNAL(rejected()),dialog,SLOT(reject())); + layout->addWidget(buttonbar); + + if(dialog->exec()==QDialog::Accepted){ + // copy points back from child + _scene->removeAll(); + const std::vector& dataNew=curve->_scene->_cvs; + typedef std::vector::const_iterator ITERATOR; + for(ITERATOR i=dataNew.begin();i!=dataNew.end();++i) + addPoint(i->_pos,i->_val,i->_interp); + _scene->emitCurveChanged(); + } +} + diff --git a/src/SeExprEditor/SeExprEdColorCurve.h b/src/SeExprEditor/SeExprEdColorCurve.h new file mode 100644 index 00000000..649f62ae --- /dev/null +++ b/src/SeExprEditor/SeExprEdColorCurve.h @@ -0,0 +1,182 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdColorCurve.h +* @brief Contains PyQt4 Ramp Widget to emulate Maya's ramp widget +* @author Arthur Shek +* @version ashek 05/04/09 Initial Version +*/ +#ifndef _SeExprEdColorCurve_h_ +#define _SeExprEdColorCurve_h_ + + +#include + +#include +#include +#include +#include +#include + +#include + +#include "SeExprEdCurve.h" + +/* + This class overrides QGraphicsScene so we can handle mouse + press, drag and keyboard events +*/ +class CCurveScene : public QGraphicsScene +{ + Q_OBJECT + + typedef SeExpr::SeCurve T_CURVE; + typedef T_CURVE::InterpType T_INTERP ; + +public: + CCurveScene(); + ~CCurveScene(); + + void addPoint(double x, const SeVec3d y, const T_INTERP interp, const bool select=true); + + void removePoint(const int index); + void removeAll(); + + virtual void keyPressEvent(QKeyEvent *event); + + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent); + + void drawRect(); + + void drawPoints(); + + QPixmap& getPixmap(); + void emitCurveChanged(); + + void rebuildCurve(); + + std::vector _cvs; // unsorted cvs + + friend class SeExprEdColorCurve; +private: + T_CURVE* _curve; +public slots: + void interpChanged(const int interp); + void selPosChanged(double pos); + void selValChanged(const SeVec3d& val); + void resize(const int width, const int height); + +signals: + void cvSelected(double x, const SeVec3d y, const T_INTERP interp); + void curveChanged(); + +private: + QByteArray getCPixmap(); + + int _width; + int _height; + SeVec3d _color; + T_INTERP _interp; + std::vector _circleObjects; + int _selectedItem; + QPixmap _pixmap; + bool _pixmapDirty; + QWidget *_baseRectW; + QGraphicsProxyWidget *_baseRect; + bool _lmb; +}; + + +class SeExprEdCBoxWidget : public QWidget +{ + Q_OBJECT +public: + SeExprEdCBoxWidget(CCurveScene* curveScene, QWidget* parent = 0) : QWidget(parent), _curveScene(curveScene) {} + ~SeExprEdCBoxWidget() {} + +protected: + virtual void paintEvent(QPaintEvent* event); + +private: + CCurveScene* _curveScene; +}; + + +class SeExprEdCSwatchFrame : public QFrame +{ + Q_OBJECT +public: + SeExprEdCSwatchFrame(SeVec3d value, QWidget* parent = 0); + ~SeExprEdCSwatchFrame() {} + + void setValue(const SeVec3d &value); + SeVec3d getValue() const; + +protected: + virtual void paintEvent(QPaintEvent* event); + virtual void mousePressEvent(QMouseEvent* event); + +signals: + void selValChangedSignal(SeVec3d value); + void swatchChanged(QColor color); + +private: + SeVec3d _value; + QColor _color; +}; + + +class SeExprEdColorCurve : public QWidget +{ + Q_OBJECT + + typedef SeExpr::SeCurve T_CURVE; + typedef T_CURVE::InterpType T_INTERP ; + +public: + SeExprEdColorCurve(QWidget* parent = 0, QString pLabel = "", QString vLabel = "", QString iLabel = "", + bool expandable=true); + ~SeExprEdColorCurve() {} + + // Convenience Functions + void addPoint(const double x, const SeVec3d y, const T_INTERP interp, bool select=false); + void setSwatchColor(QColor color); + QColor getSwatchColor(); + + CCurveScene *_scene; + +public slots: + void cvSelectedSlot(const double pos, const SeVec3d val, const T_INTERP interp); + void selPosChanged(); + void openDetail(); +private slots: + void internalSwatchChanged(QColor color); + +signals: + void selPosChangedSignal(double pos); + void selValChangedSignal(SeVec3d val); + void swatchChanged(QColor color); + + +private: + QLineEdit *_selPosEdit; + SeExprEdCSwatchFrame *_selValEdit; + QComboBox *_interpComboBox; +}; +#endif + diff --git a/src/SeExprEditor/SeExprEdCompletionModel.cpp b/src/SeExprEditor/SeExprEdCompletionModel.cpp new file mode 100644 index 00000000..743279ee --- /dev/null +++ b/src/SeExprEditor/SeExprEdCompletionModel.cpp @@ -0,0 +1,128 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdCompletionModel.h +* @brief This provides an exression editor for SeExpr syntax with auto ui features +* @author aselle +*/ +#include +#include +#include +#include "SeExprEdCompletionModel.h" + +std::vector SeExprEdCompletionModel::builtins; + +SeExprEdCompletionModel::SeExprEdCompletionModel(QObject* parent) + :QAbstractItemModel(parent) +{ + if(builtins.size()==0){ + std::vector builtins_std; + SeExprFunc::getFunctionNames(builtins_std); + for(unsigned int i=0;i::iterator i=functionNameToFunction.find(s); + if(i!=functionNameToFunction.end()){ + return functions_comment[i->second]; + }else + return SeExprFunc::getDocString(s.toStdString().c_str()).c_str(); +} diff --git a/src/SeExprEditor/SeExprEdCompletionModel.h b/src/SeExprEditor/SeExprEdCompletionModel.h new file mode 100644 index 00000000..7b518107 --- /dev/null +++ b/src/SeExprEditor/SeExprEdCompletionModel.h @@ -0,0 +1,92 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdCompletionModel.h +* @brief Provides a model for providing completion items +* @author aselle +*/ + +#ifndef SeExprEdCompletionModel_h +#define SeExprEdCompletionModel_h + +#include +#include +#include +#include + +class SeExprEdCompletionModel:public QAbstractItemModel // ItemModel +{ +public: + // clear/add functions (these are ones that will be resolved with resolveFunc() + void clearFunctions(); + void addFunction(const QString& function,const QString& docString); + + // clear/add user variables (these are ones that will be resolved with resolveVar() + void clearVariables(); + void addVariable(const QString& str,const QString& comment); + + // add extras + void syncExtras(const SeExprEdCompletionModel& otherModel); + + SeExprEdCompletionModel(QObject* parent=0); + + QModelIndex index(int row,int column,const QModelIndex&) const + {return createIndex(row,column,0);} + + QModelIndex parent(const QModelIndex&) const + {return QModelIndex();} + + int rowCount(const QModelIndex& parent=QModelIndex()) const + { + Q_UNUSED(parent); + int count= builtins.size()+functions.size()+variables.size()+local_variables.size(); + return count; + } + + int columnCount(const QModelIndex& parent) const + {Q_UNUSED(parent); return 2;} + + QString getFirstLine(const std::string& all) const + { + size_t newline=all.find("\n"); + if(newline!=std::string::npos) return QString(all.substr(0,newline).c_str()); + else return QString(all.c_str()); + } + + QVariant data(const QModelIndex& index,int role=Qt::DisplayRole) const; + + QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const + { + Q_UNUSED(orientation); + if(role==Qt::DisplayRole) return QVariant(""); + else if(role==Qt::SizeHintRole){ + if(section==0) return QVariant(QSize(100,1)); + else return QVariant(QSize(200,1)); + }else return QVariant(); + } + std::vector local_variables; // only the expression editor itself should modify these + + QString getDocString(const QString& s); +private: + static std::vector builtins; + std::vector functions,functions_comment; + std::map functionNameToFunction; + std::vector variables,variables_comment; +}; + + + +#endif diff --git a/src/SeExprEditor/SeExprEdControl.cpp b/src/SeExprEditor/SeExprEdControl.cpp new file mode 100644 index 00000000..cb0a7475 --- /dev/null +++ b/src/SeExprEditor/SeExprEdControl.cpp @@ -0,0 +1,832 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEditor.cpp +* @brief This provides an exression editor for SeExpr syntax with auto ui features +* @author aselle +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SeExprEdControl.h" +#include "SeExprEdColorCurve.h" +#include "SeExprEdFileDialog.h" +#include "SeExprEdEditable.h" +#ifdef SEEXPR_USE_ANIMLIB +# include +# include +#endif + +/* XPM */ +static const char *refreshXPM[]={ +"20 20 4 1", +"# c #303030", +"a c #585858", +"b c #c3c3c3", +". c #dcdcdc", +"....................", +"....................", +"....................", +".......#aaaa#.......", +".....#########......", +"....###bbbbb###.....", +"....##b.....b##.....", +"...bb#b.....b##.....", +"...bbbb....aaaaaa...", +"...........aaaaaa...", +"....##......####....", +"...####......##.....", +"..######............", +"..aaa#aa............", +"....##......bbb.....", +"....##b...bbbab.....", +"....a#abbbb##ab.....", +".....#a####aa#b.....", +".....aaaaaaa#.b.....", +"...................."}; + +/* XPM */ +static const char *graphXPM[]={ +"20 20 5 1", +"c c #000040", +"a c #303030", +"# c #58a8ff", +". c #dcdcdc", +"b c #ff0000", +"..........#a.a......", +"..........#a.a.....b", +"..........#.a.....bb", +"..........#aa....bb.", +"..........#.....bb..", +"..........#....bb...", +"..........#....bb...", +"....bbb...#...bb....", +"...bbbbb..#..bbb....", +"...b...bbb#.bbb.....", +"..bb....bb#bbb......", +"##bb####bbbbb#######", +".bb......bbb....c.c.", +".bb.......#......c..", +".b........#.....c.c.", +"bb........#.........", +"b.........#.........", +"..........#.........", +"..........#.........", +"..........#........."}; + + +/* XPM */ +static const char *directoryXPM[]={ +"20 20 3 1", +". c None", +"# c #000000", +"a c #d8c59e", +"....................", +"....................", +"....................", +"....................", +"...........#######..", +"...........#aaaaa#..", +"..##########aaaaa#..", +"..#aaaaaaaaaaaaaa#..", +"..#aaaaaaaaaaaaaa#..", +"..#aaaaaaaaaaaaaa#..", +"..#aaaaaaaaaaaaaa#..", +"..#aaaaaaaaaaaaaa#..", +"..#aaaaa##a##a##a#..", +"..#aaaaa##a##a##a#..", +"..#aaaaaaaaaaaaaa#..", +"..################..", +"....................", +"....................", +"....................", +"...................."}; + +/* XPM */ +static const char *fileXPM[]={ +"20 20 5 1", +". c None", +"# c #000000", +"c c #303030", +"b c #a79b80", +"a c #ddcdaa", +"....................", +"....................", +"....#########.......", +"....#aaaaaaa##......", +"....#aaaaaaa#b#.....", +"....#aaaaaaa#bb#....", +"....#aaaaaaa####....", +"....#aaaaaaaaaa#....", +"....#aaaaaaaaaa#....", +"....#aaaaaaaaaa#....", +"....#aaaaaaaaaa#....", +"....#aaaaaaaaaa#....", +"....#aaaaaaaaaa#....", +"....#aaaaaaaaaa#....", +"....#aaaaaaaaaa#....", +"....#accaccacca#....", +"....#accaccacca#....", +"....#aaaaaaaaaa#....", +"....############....", +"...................."}; + + + +void SeExprEdSlider::mousePressEvent(QMouseEvent* e) +{ + mouseMoveEvent(e); +} + +void SeExprEdSlider::mouseMoveEvent(QMouseEvent* e) +{ + float r = maximum()-minimum(); + float v = ((float)(e->x()-2)*r/(width()-5))+minimum()+.5f; + int iv = std::min(std::max((int)v,minimum()),maximum()); + setValue(iv); +} + +void SeExprEdSlider::paintEvent(QPaintEvent* e) +{ + Q_UNUSED(e); + QPainter p(this); + + float v = value(); + float r = maximum()-minimum(); + int linepos = (int)((v-minimum())/r*(width()-5)+2); + + QColor qcol = palette().color(QPalette::Dark); + QColor bcol = palette().color(QPalette::Midlight); + QColor dcol = bcol.lighter(140); + QColor bgcol = palette().color(QPalette::Base); + + if (underMouse()) + { + bcol = bcol.lighter(110); + bgcol = bgcol.lighter(110); + int mx = mapFromGlobal(QCursor::pos()).x(); + if (abs(linepos-mx)<4) dcol = dcol.lighter(200); + } + + p.fillRect(1,1,width()-1,height()-2,bgcol); + p.fillRect(1,1,linepos-1,height()-2,bcol); + + QPen pen = p.pen(); + + pen.setColor(dcol); + p.setPen(pen); + pen.setWidth(3); + p.setPen(pen); + p.drawLine(linepos,2,linepos,height()-2); + pen.setWidth(1); + pen.setColor(qcol); + p.setPen(pen); + p.drawLine(linepos-2,1,linepos-2,height()-1); + p.drawLine(linepos+2,1,linepos+2,height()-1); + + pen.setWidth(1); + pen.setColor(qcol); + p.setPen(pen); + p.drawRect(0,0,width()-1,height()-1); +} + +SeExprEdChannelSlider::SeExprEdChannelSlider(int id, QWidget* parent) + : QWidget(parent), _id(id), _value(0) +{ +} + +void SeExprEdChannelSlider::paintEvent(QPaintEvent* e) +{ + Q_UNUSED(e); + if (_value < 0 || _value > 1) return; + int x = int(_value * (width()-3) + 0.5); + QPainter p(this); + p.fillRect(contentsRect(), _col); + p.fillRect(x, 0, 3, height(), QColor(64,64,64)); +} + +void SeExprEdChannelSlider::mousePressEvent(QMouseEvent* e) +{ + mouseMoveEvent(e); +} + + +void SeExprEdChannelSlider::mouseMoveEvent(QMouseEvent* e) +{ + setValue(clamp(float(e->x()-1) / (width()-3), 0, 1)); +} + + +void SeExprEdChannelSlider::setValue(float value) +{ + if (value == _value) return; + _value = value; + emit valueChanged(_id, value); + update(); +} + + +SeExprEdControl::SeExprEdControl(int id,SeExprEdEditable* editable,bool showColorLink) + :_id(id),_updating(false),_editable(editable) +{ + hbox=new QHBoxLayout(this); + hbox->setSpacing(2); + hbox->setMargin(0); + + _colorLinkCB=new QCheckBox(this); + _colorLinkCB->setFixedWidth(14); + _colorLinkCB->setFocusPolicy(Qt::NoFocus); + connect(_colorLinkCB,SIGNAL(stateChanged(int)),this,SLOT(linkStateChange(int))); + hbox->addWidget(_colorLinkCB); + + _label = new QLabel(QString("")+editable->name.c_str()+""); + _label->setFixedWidth(72); + _label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + _label->setIndent(2); + _label->setAutoFillBackground(true); + hbox->addWidget(_label); + + if(!showColorLink){ + _colorLinkCB->setHidden(true); + _label->setFixedWidth(84); + }else{ + _colorLinkCB->setHidden(false); + _label->setFixedWidth(84-_colorLinkCB->width()+2); + } + +} + +void SeExprEdControl::linkStateChange(int state) +{ + if(_updating) return; + + if(state==Qt::Checked){ + emit linkColorLink(_id); + emit linkColorEdited(_id,getColor()); + }else{ + emit linkColorLink(-1); + } +} + +void SeExprEdControl::linkDisconnect(int newId) +{ + if(newId!=_id){ + _updating = 1; + _colorLinkCB->setChecked(false); + _updating = 0; + } +} + + + + +SeExprEdNumberControl::SeExprEdNumberControl(int id,SeExprEdNumberEditable* editable) + :SeExprEdControl(id,editable,false),_numberEditable(editable) +{ + + // slider + float smin = editable->min, smax = editable->max; + if(!_numberEditable->isInt) { smin *= 1e5; smax *= 1e5; } + float srange = smax-smin; + _slider = new SeExprEdSlider(Qt::Horizontal,this); + _slider->setRange(int(smin),int(smax)); + _slider->setTickInterval(std::max(1,int(srange/10))); + _slider->setSingleStep(std::max(1,int(srange/50))); + _slider->setPageStep(std::max(1,int(srange/10))); + _slider->setMinimumWidth(0); + _slider->setFixedHeight(16); + _slider->setFocusPolicy(Qt::ClickFocus); + hbox->addWidget(_slider, 3); + // edit box + _edit = new SeExprEdLineEdit(0,this); + _edit->setMinimumWidth(0); + _edit->setFixedHeight(16); + hbox->addWidget(_edit); + connect(_edit,SIGNAL(textChanged(int,const QString&)),SLOT(editChanged(int,const QString&))); + connect(_slider, SIGNAL(valueChanged(int)), SLOT(sliderChanged(int))); + // show current values + updateControl(); +} + +void SeExprEdNumberControl::sliderChanged(int value) +{ + if (_updating) return; + setValue(_numberEditable->isInt ? value : value*1e-5); + +} + +void SeExprEdNumberControl::editChanged(int id,const QString& text) +{ + Q_UNUSED(id); + if (_updating) return; + bool ok = 0; + float val = text.toFloat(&ok); + if (!ok) return; + setValue(val); +} + +void SeExprEdNumberControl::updateControl() +{ + _updating = 1; + int sliderval = int(_numberEditable->isInt ? _numberEditable->v : _numberEditable->v*1e5); + if (sliderval != _slider->value()) _slider->setValue(sliderval); + _edit->setText(QString("%1") + .arg(_numberEditable->v, 0, 'f', _numberEditable->isInt ? 0 : 3)); + _updating=0; +} + +void SeExprEdNumberControl::setValue(float value) +{ + //std::cerr<<"In setValue "<<_id<v-value) < 1e-5) return; + _numberEditable->v=value; + updateControl(); + emit controlChanged(_id); +} + +SeExprEdVectorControl::SeExprEdVectorControl(int id,SeExprEdVectorEditable* editable) + :SeExprEdControl(id,editable,true),_numberEditable(editable) +{ + + if(_numberEditable->isColor){ + _swatch=new SeExprEdCSwatchFrame(editable->v); + _swatch->setFixedWidth(38); + _swatch->setFixedHeight(20); + connect(_swatch,SIGNAL(swatchChanged(QColor)),this,SLOT(swatchChanged(QColor))); + hbox->addWidget(_swatch); + } + for(int i=0;i<3;i++){ + QVBoxLayout* vbl=new QVBoxLayout(); + hbox->addLayout(vbl); + vbl->setMargin(0); + vbl->setSpacing(0); + + SeExprEdLineEdit* edit = new SeExprEdLineEdit(i, this); + vbl->addWidget(edit); + _edits[i]=edit; + edit->setMinimumWidth(0); + edit->setFixedHeight(16); + + SeExprEdChannelSlider* slider = new SeExprEdChannelSlider(i, this); + vbl->addWidget(slider); + _sliders[i]=slider; + slider->setFixedHeight(6); + // set color + static const QColor rgb[3] = { QColor(128,64,64), QColor(64,128,64), QColor(64,64,128) }; + if(_numberEditable->isColor) slider->setDisplayColor(rgb[i]); + + connect(edit,SIGNAL(textChanged(int,const QString&)),SLOT(editChanged(int,const QString&))); + connect(slider, SIGNAL(valueChanged(int,float)), SLOT(sliderChanged(int,float))); + + } + // update controls + updateControl(); +} + +void SeExprEdVectorControl::swatchChanged(QColor gah) +{ + Q_UNUSED(gah); + SeVec3d color=_swatch->getValue(); + setValue(0,color[0]); + setValue(1,color[1]); + setValue(2,color[2]); +} + +QColor SeExprEdVectorControl::getColor() +{ + return QColor::fromRgbF(clamp(_numberEditable->v[0],0,1), + clamp(_numberEditable->v[1],0,1), + clamp(_numberEditable->v[2],0,1)); +} + +void SeExprEdVectorControl::setColor(QColor color) +{ + setValue(0,color.redF()); + setValue(1,color.greenF()); + setValue(2,color.blueF()); +} + +void SeExprEdVectorControl::sliderChanged(int id,float value) +{ + if (_updating) return; + setValue(id,_numberEditable->min + value * (_numberEditable->max-_numberEditable->min)); + if (_numberEditable->isColor) emit linkColorEdited(_id,getColor()); +} + +void SeExprEdVectorControl::editChanged(int id,const QString& text) +{ + if (_updating) return; + bool ok = 0; + float val = text.toFloat(&ok); + if (!ok) return; + setValue(id,val); +} + +void SeExprEdVectorControl::updateControl() +{ +// //std::cerr<<"In update control "<<_id<setText(QString("%1") + .arg(_numberEditable->v[i], 0, 'f', 3)); + double min=_numberEditable->min,max=_numberEditable->max; + for (unsigned int i = 0; i < 3; i++){ + _sliders[i]->setValue((_numberEditable->v[i]-min)/(max-min)); + } + if(_numberEditable->isColor){ + //std::cerr<<"trying to set color"<v; + float r = clamp(val[0],0,1); + float g = clamp(val[1],0,1); + float b = clamp(val[2],0,1); + float lum = r*.2+g*.7+b*.1; + //std::cerr<<" rgb "<setPalette(pal); + + } + _updating = 0; +} + +void SeExprEdVectorControl::setValue(int n,float value) +{ + if (n < 0 || n >= 3) return; + if (fabs(_numberEditable->v[n]-value) < 1e-5) return; + _numberEditable->v[n] = value; + if(_swatch) _swatch->setValue(_numberEditable->v); + updateControl(); + emit controlChanged(_id); +} + +SeExprEdStringControl::SeExprEdStringControl(int id,SeExprEdStringEditable* editable) + :SeExprEdControl(id,editable,false),_stringEditable(editable) +{ + // make line edit + _edit=new QLineEdit(); + _edit->setFixedHeight(20); + connect(_edit,SIGNAL(textChanged(const QString&)),SLOT(textChanged(const QString&))); + // make a button if we are a file or directory + if(_stringEditable->type=="file" || _stringEditable->type=="directory"){ + QPushButton* button=new QPushButton(); + button->setFixedSize(20,20); + + hbox->addWidget(_edit,3); + hbox->addWidget(button,1); + if(_stringEditable->type=="directory"){ + connect(button,SIGNAL(clicked()),SLOT(directoryBrowse())); + button->setIcon(QIcon(QPixmap(directoryXPM))); + } else if(_stringEditable->type=="file"){ + connect(button,SIGNAL(clicked()),SLOT(fileBrowse())); + button->setIcon(QIcon(QPixmap(fileXPM))); + } + + }else{ + hbox->addWidget(_edit,3); + } + // update controls + updateControl(); +} + +void SeExprEdStringControl::fileBrowse() +{ + SeExprEdFileDialog dialog(this); + dialog.setPreview(); + QString newFilename=dialog.getOpenFileName("Please choose a file",_edit->text(),tr("Images (*.tif *.tx *.jpg *.ptx *.png)")); + if(newFilename!="") _edit->setText(newFilename); +} + +void SeExprEdStringControl::directoryBrowse() +{ + SeExprEdFileDialog dialog(this); + dialog.setPreview(); + QString newFilename=dialog.getExistingDirectory("Please choose a file",_edit->text()); + if(newFilename!="") _edit->setText(newFilename); +} + +void SeExprEdStringControl::updateControl() +{ + _edit->setText(_stringEditable->v.c_str()); +} + +void SeExprEdStringControl::textChanged(const QString& newText) +{ + if(_updating) return; + _stringEditable->v=newText.toStdString(); + emit controlChanged(_id); +} + +SeExprEdCurveControl::SeExprEdCurveControl(int id,SeExprEdCurveEditable* editable) + :SeExprEdControl(id,editable,false),_curveEditable(editable) +{ + _curve = new SeExprEdCurve(this, "Pos:", "Val:", "Interp:"); + _curve->setFixedHeight(80); + + const int numVal = _curveEditable->cvs.size(); + for (int i = 0; i < numVal; i++) { + const SeExpr::SeCurve::CV& cv=_curveEditable->cvs[i]; + _curve->addPoint(cv._pos,cv._val,cv._interp); + } + hbox->addWidget(_curve, 3); + connect(_curve->_scene, SIGNAL(curveChanged()), SLOT(curveChanged())); + // unneded? updateControl(); +} + +void SeExprEdCurveControl::curveChanged() +{ + if(_curve && _curveEditable){ + _curveEditable->cvs=_curve->_scene->_cvs; + emit controlChanged(_id); + } +} + +SeExprEdCCurveControl::SeExprEdCCurveControl(int id,SeExprEdColorCurveEditable* editable) + :SeExprEdControl(id,editable,true),_curveEditable(editable) +{ + _curve = new SeExprEdColorCurve(this, "Pos:", "Val:", "Interp:"); + _curve->setFixedHeight(80); + + const int numVal = _curveEditable->cvs.size(); + for (int i = 0; i < numVal; i++) { + const SeExpr::SeCurve::CV& cv=_curveEditable->cvs[i]; + _curve->addPoint(cv._pos,cv._val,cv._interp); + } + hbox->addWidget(_curve, 3); + connect(_curve->_scene, SIGNAL(curveChanged()), SLOT(curveChanged())); + // unneeded? updateControl(); +} + +void SeExprEdCCurveControl::curveChanged() +{ + if(_curve && _curveEditable){ + _curveEditable->cvs=_curve->_scene->_cvs; + emit controlChanged(_id); + + } +} + + +QColor SeExprEdCCurveControl::getColor() +{ + return _curve->getSwatchColor(); +} + +void SeExprEdCCurveControl::setColor(QColor color) +{ + _curve->setSwatchColor(color); +} + +struct SeExprEdGraphPreview:public QWidget +{ + std::vector x,y; + std::vector cpx,cpy; + float xmin,xmax,ymin,ymax,dx,dy;; + float win_xmin,win_xmax,win_ymin,win_ymax,win_dx,win_dy;; + SeExprEdGraphPreview(QWidget* parent=0) + :QWidget(parent) + { + win_xmin=-1.; + win_xmax=2.; + win_ymin=-1; + win_ymax=2.; + } + + QPointF toScreen(float x,float y){ + return QPointF((x-win_xmin)*win_dx,height()-(y-win_ymin)*win_dy); + } + + + void paintEvent(QPaintEvent* event){ + QWidget::paintEvent(event); + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing,true); + painter.setPen(QColor(255,255,255)); + win_xmin=xmin;win_xmax=xmax; + win_ymin=ymin;win_ymax=ymax; + float percentXpad=.1*(win_xmax-win_xmin); + float percentYpad=.1*(win_ymax-win_ymin); + win_xmin-=percentXpad; + win_xmax+=percentXpad; + win_ymin-=percentYpad; + win_ymax+=percentYpad; + + // make space for text + int x_pad_in_pixels=25,y_pad_in_pixels=15; + float xpad=x_pad_in_pixels*(win_xmax-win_xmin)/(width()-x_pad_in_pixels); + float ypad=y_pad_in_pixels*(win_ymax-win_ymin)/(height()-y_pad_in_pixels); + win_ymin-=ypad; + win_xmax+=xpad; + + win_dx=width()/(win_xmax-win_xmin); + win_dy=height()/(win_ymax-win_ymin); + + //int h=height(); + QPainterPath path; + QRectF fullarea(toScreen(win_xmin,win_ymax),toScreen(win_xmax,win_ymin)); + QBrush darkbrush(QColor(100,100,100),Qt::SolidPattern); + QRectF area(toScreen(xmin,ymax),toScreen(xmax,ymin)); + QBrush brush(QColor(150,150,150),Qt::SolidPattern); + //painter.fillRect(fullarea,darkbrush); + //painter.setBrush(darkbrush); + //painter.drawRoundedRect(fullarea,3,3); + //painter.setBrush(QBrush()); + painter.fillRect(area,brush); + if(x.size()>0){ + path.moveTo(toScreen(x[0],y[0])); + for(int i=1;i<(int)x.size();i++) + path.lineTo(toScreen(x[i],y[i])); + + } + QRectF right(toScreen(xmax,ymax),toScreen(win_xmax,ymin)); + QRectF bottom(toScreen(xmin,ymin),toScreen(xmax,win_ymin)); + + painter.setPen(QColor(75,50,50)); + painter.drawPath(path); + + painter.setPen(QPen()); + painter.drawText(right,Qt::AlignTop|Qt::AlignLeft,QString("%1").arg(ymax,0,'f',1)); + painter.drawText(right,Qt::AlignBottom|Qt::AlignLeft,QString("%1").arg(ymin,0,'f',1)); + painter.drawText(bottom,Qt::AlignTop|Qt::AlignLeft,QString("%1").arg(xmin,0,'f',1)); + painter.drawText(bottom,Qt::AlignTop|Qt::AlignRight,QString("%1").arg(xmax,0,'f',1)); + + painter.setBrush(QBrush(QColor(0,0,0),Qt::SolidPattern)); + for(size_t i=0;i0){ + const animlib::AnimKeyframe* key=&*curve.getFirstKey(); + xmin=key[0].getTime(); + xmax=key[numKeys-1].getTime(); + ymin=FLT_MAX; + ymax=-FLT_MAX; + + for(int i=0;isetMinimumWidth(200); + _preview->setMinimumHeight(60); + hbox->addWidget(_preview); + //QPushButton* button=new QPushButton(); + //button->setIcon(QIcon(QPixmap(graphXPM))); + Q_UNUSED(graphXPM) + QPushButton* refreshButton=new QPushButton(); + refreshButton->setMaximumWidth(30); + refreshButton->setIcon(QIcon(QPixmap(refreshXPM))); + QPushButton* expandButton=new QPushButton(">"); + expandButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding); + expandButton->setFixedWidth(15); + hbox->addWidget(expandButton); + //hbox->addWidget(button); + refreshButton->setVisible(_editable->link!=""); + hbox->addWidget(refreshButton); + +#ifdef SEEXPR_USE_ANIMLIB + _preview->sample(editable->curve); +#endif + connect(expandButton,SIGNAL(clicked()),this,SLOT(editGraphClicked())); + //connect(_preview,SIGNAL(clicked()),this,SLOT(editGraphClicked())); + connect(refreshButton,SIGNAL(clicked()),this,SLOT(refreshClicked())); +} + +#ifdef SEEXPR_USE_ANIMLIB +#include +#endif + +void SeExprEdAnimCurveControl::refreshClicked() +{ + if(callback){ +#ifdef SEEXPR_USE_ANIMLIB + callback(_editable->link,_editable->curve); + _preview->sample(_editable->curve); + _preview->repaint(); + emit controlChanged(_id); +#endif + } +} + +void SeExprEdAnimCurveControl::editGraphClicked(){ +#ifdef SEEXPR_USE_ANIMLIB + QDialog* dialog=new QDialog(this); + CETool* tool=new CETool; + animlib::AnimAttrID attr1("",""); + animlib::AnimCurve& anim=*new animlib::AnimCurve(attr1); + anim=_editable->curve; + + QWidget *widg; + tool->map(widg,0); + QVBoxLayout* layout=new QVBoxLayout(); + dialog->resize(QSize(1024,640)); + dialog->setLayout(layout); + layout->addWidget(widg); + tool->addCurve(&anim); + + QDialogButtonBox* buttonbar=new QDialogButtonBox(); + buttonbar->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + connect(buttonbar,SIGNAL(accepted()),dialog,SLOT(accept())); + connect(buttonbar,SIGNAL(rejected()),dialog,SLOT(reject())); + layout->addWidget(buttonbar); + + if(dialog->exec()==QDialog::Accepted){ + // copy points back from child + _editable->curve=anim; + _preview->sample(_editable->curve); + _preview->repaint(); + emit controlChanged(_id); + } +#endif +} + +void SeExprEdAnimCurveControl::setAnimCurveCallback(AnimCurveCallback newCallback) +{ + callback=newCallback; +} + +SeExprEdAnimCurveControl::AnimCurveCallback SeExprEdAnimCurveControl::callback=0; + + + + + + + + + + + + diff --git a/src/SeExprEditor/SeExprEdControl.h b/src/SeExprEditor/SeExprEdControl.h new file mode 100644 index 00000000..13d50ecb --- /dev/null +++ b/src/SeExprEditor/SeExprEdControl.h @@ -0,0 +1,285 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef _SeExprEdSlider_h_ +#define _SeExprEdSlider_h_ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SeExprEdCurve.h" +#include "SeExprEdColorCurve.h" + +class SeExprEditor; +class QLabel; +class SeExprEdColorCurve; +class QHBoxLayout; +class SeExprEdCSwatchFrame; +class SeExprEdEditable; +class SeExprEdStringEditable; +class SeExprEdVectorEditable; +class SeExprEdNumberEditable; +class SeExprEdAnimCurveEditable; +template struct SeExprEdGenericCurveEditable; +typedef SeExprEdGenericCurveEditable SeExprEdColorCurveEditable; +typedef SeExprEdGenericCurveEditable SeExprEdCurveEditable; + +namespace animlib{ +class AnimCurve; +} + +/// Base class for all controls for SeExpressions +class SeExprEdControl:public QWidget +{ + Q_OBJECT; + +protected: + int _id; + bool _updating; // whether to send events (i.e. masked when self editing) + QHBoxLayout* hbox; + QCheckBox* _colorLinkCB; + QLabel* _label; + + SeExprEdEditable* _editable; + +public: + SeExprEdControl(int id,SeExprEdEditable* editable,bool showColorLink); + virtual ~SeExprEdControl(){} + + /// Interface for getting the color (used for linked color picking) + virtual QColor getColor(){return QColor();} + /// Interface for setting the color (used for linked color picking) + virtual void setColor(QColor color){Q_UNUSED(color)}; + +signals: + // sends that the control has been changed to the control collection + void controlChanged(int id); + // sends the new color to the control collection + void linkColorEdited(int id,QColor color); + // sends that a color link is desired to the control collection + void linkColorLink(int id); +public slots: + // receives that the link should be changed to the given state (0=off,1=on) + void linkStateChange(int state); +public: + // notifies this that the link should be disconnected + void linkDisconnect(int newId); +}; + + +/// clamp val to the specified range [minval,maxval] +template T clamp(const T val,const T2 minval,const T3 maxval) +{ + if(valmaxval) return maxval; + return val; +} + +/// Line Editor Widget(used for numbers) +// TODO: can this now be removed? +class SeExprEdLineEdit : public QLineEdit +{ + Q_OBJECT + public: + SeExprEdLineEdit(int id, QWidget* parent); + virtual void setText(const QString& t) + { + if (_signaling) return; + QLineEdit::setText(t); + } + + signals: + void textChanged(int id, const QString& text); + + private slots: + void textChangedCB(const QString& text); + + private: + int _id; + bool _signaling; +}; + +/// Generic Slider (used for int and float sliders) +class SeExprEdSlider : public QSlider +{ + Q_OBJECT + public: + SeExprEdSlider(QWidget* parent = 0) : QSlider(parent) {} + SeExprEdSlider(Qt::Orientation orientation, QWidget* parent = 0) + : QSlider(orientation, parent) {} + virtual void mousePressEvent(QMouseEvent* e); + virtual void mouseMoveEvent(QMouseEvent* e); + virtual void paintEvent(QPaintEvent* e); + virtual void leaveEvent(QEvent* event ) { Q_UNUSED(event); update(); } + virtual void enterEvent(QEvent* event ) { Q_UNUSED(event); update(); } + virtual void wheelEvent(QWheelEvent* e) { e->ignore(); } +}; + +/// Channel Slider (i.e. for colors) +class SeExprEdChannelSlider : public QWidget +{ + Q_OBJECT + public: + SeExprEdChannelSlider(int id, QWidget* parent); + virtual void paintEvent(QPaintEvent* e); + virtual void mousePressEvent(QMouseEvent* e); + virtual void mouseMoveEvent(QMouseEvent* e); + virtual void wheelEvent(QWheelEvent* e) { e->ignore(); } + float value() const { return _value; } + void setDisplayColor( QColor c ) { _col = c; } + + public slots: + void setValue(float value); + + signals: + void valueChanged(int id, float value); + private: + int _id; + float _value; + QColor _col; +}; + +/// Number slider for either float or int data +class SeExprEdNumberControl:public SeExprEdControl +{ + Q_OBJECT + + /// Pointer to the number control model + SeExprEdNumberEditable* _numberEditable; + /// Slider for the number + SeExprEdSlider* _slider; + /// Text box for the number + SeExprEdLineEdit* _edit; +public: + SeExprEdNumberControl(int id,SeExprEdNumberEditable* number); +private: + /// Update the model with the value and notify the collection + void setValue(float value); + /// Update values in slider and textbox given what the model contains + void updateControl(); +private slots: + void sliderChanged(int val); + void editChanged(int id,const QString& text); +}; + +/// A vector or color control (named vector because it edits a SeVec3d literal) +class SeExprEdVectorControl:public SeExprEdControl +{ + Q_OBJECT + + /// Number model + SeExprEdVectorEditable* _numberEditable; + /// All three line edit widgets (for each component) + SeExprEdLineEdit* _edits[3]; + SeExprEdCSwatchFrame* _swatch;; + /// All three channel sliders (for each component) + SeExprEdChannelSlider* _sliders[3]; +public: + SeExprEdVectorControl(int id,SeExprEdVectorEditable* number); + + QColor getColor(); + void setColor(QColor color); +private: + /// set the value in the model (in response to editing from controls) + void setValue(int id,float value); + /// update the individual slider and eidt box controls + void updateControl(); +private slots: + void sliderChanged(int id,float val); + void editChanged(int id,const QString& text); + void swatchChanged(QColor color); +}; + +/// A control for editing strings, filenames, and directories +class SeExprEdStringControl:public SeExprEdControl +{ + Q_OBJECT + + /// model for the string control + SeExprEdStringEditable* _stringEditable; + /// Edit box for the string + QLineEdit* _edit; +public: + SeExprEdStringControl(int id,SeExprEdStringEditable* stringEditable); +private: + void updateControl(); +private slots: + void textChanged(const QString& newText); + void fileBrowse(); + void directoryBrowse(); +}; + +/// Control for editing a normal curve ramp +class SeExprEdCurveControl:public SeExprEdControl +{ + Q_OBJECT + + /// curve model + SeExprEdCurveEditable* _curveEditable; + /// curve edit widget + SeExprEdCurve* _curve; +public: + SeExprEdCurveControl(int id,SeExprEdCurveEditable* stringEditable); +private slots: + void curveChanged(); +}; + +/// Control for editing a color ramp curve +class SeExprEdCCurveControl:public SeExprEdControl +{ + Q_OBJECT + + /// color curve model + SeExprEdColorCurveEditable* _curveEditable; + /// color curve widget + SeExprEdColorCurve* _curve; +public: + SeExprEdCCurveControl(int id,SeExprEdColorCurveEditable* stringEditable); + QColor getColor(); + void setColor(QColor color); +private slots: + void curveChanged(); +}; + +/// Anim curve control +class SeExprEdGraphPreview; +class SeExprEdAnimCurveControl:public SeExprEdControl +{ + Q_OBJECT; + + SeExprEdAnimCurveEditable* _editable; + SeExprEdGraphPreview* _preview; +public: + SeExprEdAnimCurveControl(int id,SeExprEdAnimCurveEditable* curveEditable); + typedef void (*AnimCurveCallback)(const std::string&,animlib::AnimCurve& curve); + static void setAnimCurveCallback(AnimCurveCallback callback); + +public slots: + void editGraphClicked(); + +private slots: + void refreshClicked(); + +private: + static AnimCurveCallback callback; +}; + +#endif diff --git a/src/SeExprEditor/SeExprEdControlCollection.cpp b/src/SeExprEditor/SeExprEdControlCollection.cpp new file mode 100644 index 00000000..80cee7cc --- /dev/null +++ b/src/SeExprEditor/SeExprEdControlCollection.cpp @@ -0,0 +1,425 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEditor.cpp +* @brief This provides an expression editor for SeExpr syntax with auto ui features +* @author aselle +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "SeExprEditor.h" +#include "SeExprEdHighlighter.h" +#include "SeExprEdCompletionModel.h" +#include "SeExprEdCurve.h" +#include "SeExprEdColorCurve.h" +#include "SeExprEdControl.h" +#include "SeExprEdControlCollection.h" +#include "SeExprEdEditableExpression.h" +#include "SeExprEdEditable.h" + + +SeExprEdControlCollection::SeExprEdControlCollection(QWidget* parent,bool showAddButton) + :QWidget(parent),count(0),showAddButton(showAddButton),editableExpression(0) +{ + controlLayout=new QVBoxLayout(); + controlLayout->setMargin(0); + controlLayout->setSpacing(0); + controlLayout->insertStretch(-1,100); + + if(showAddButton){ + QPushButton* button=new QPushButton("Add Widget"); + button->setFocusPolicy(Qt::NoFocus); + QHBoxLayout* buttonLayout=new QHBoxLayout(); + buttonLayout->insertStretch(-1,100); + buttonLayout->addWidget(button,0); + controlLayout->addLayout(buttonLayout); + connect(button, SIGNAL(clicked()), SLOT(addControlDialog())); + } + setLayout(controlLayout); +} + +SeExprEdControlCollection::~SeExprEdControlCollection() +{ + delete editableExpression; +} + + + SeExprEdAddDialog::SeExprEdAddDialog(int& count,QWidget* parent) + :QDialog(parent) + { + QVBoxLayout *verticalLayout; + verticalLayout = new QVBoxLayout(); + verticalLayout->setSpacing(3); + verticalLayout->setMargin(3); + setLayout(verticalLayout); + QHBoxLayout *horizontalLayout = new QHBoxLayout(); + + horizontalLayout->addWidget(new QLabel("Variable")); + // TODO would be nice to unique this over multiple sessions + variableName = new QLineEdit(QString("$var%1").arg(count++)); + + horizontalLayout->addWidget(variableName); + verticalLayout->addLayout(horizontalLayout); + + tabWidget = new QTabWidget(); + + + // Curve + { + QWidget* curveTab = new QWidget(); + QFormLayout* curveLayout = new QFormLayout(curveTab); + curveLayout->setWidget(0,QFormLayout::LabelRole,new QLabel("Lookup")); + curveLookup=new QLineEdit("$u"); + curveLayout->setWidget(0,QFormLayout::FieldRole,curveLookup); + tabWidget->addTab(curveTab, QString("Curve")); + } + + // Color Curve + { + QWidget* colorCurveTab = new QWidget(); + QFormLayout* colorCurveLayout = new QFormLayout(colorCurveTab); + colorCurveLayout->setWidget(0,QFormLayout::LabelRole,new QLabel("Lookup")); + colorCurveLookup=new QLineEdit("$u"); + colorCurveLayout->setWidget(0,QFormLayout::FieldRole,colorCurveLookup); + tabWidget->addTab(colorCurveTab, QString("Color Curve")); + } + + // Anim Curve + { + QWidget* curveTab = new QWidget(); + QFormLayout* curveLayout = new QFormLayout(curveTab); + curveLayout->setWidget(0,QFormLayout::LabelRole,new QLabel("Lookup")); + curveLayout->setWidget(1,QFormLayout::LabelRole,new QLabel("Link")); + animCurveLookup=new QLineEdit("$frame"); + animCurveLink=new QLineEdit(""); + curveLayout->setWidget(0,QFormLayout::FieldRole,animCurveLookup); + curveLayout->setWidget(1,QFormLayout::FieldRole,animCurveLink); + tabWidget->addTab(curveTab, QString("AnimCurve")); + } + + // Integer + { + QWidget* intTab = new QWidget(); + QFormLayout* intFormLayout = new QFormLayout(intTab); + intFormLayout->setWidget(0, QFormLayout::LabelRole, new QLabel("Default")); + intFormLayout->setWidget(1, QFormLayout::LabelRole, new QLabel("Min")); + intFormLayout->setWidget(2, QFormLayout::LabelRole, new QLabel("Max")); + intDefault = new QLineEdit("0"); + intFormLayout->setWidget(0, QFormLayout::FieldRole, intDefault); + intMin = new QLineEdit("0"); + intFormLayout->setWidget(1, QFormLayout::FieldRole, intMin); + intMax = new QLineEdit("10"); + intFormLayout->setWidget(2, QFormLayout::FieldRole, intMax); + tabWidget->addTab(intTab, QString("Int")); + } + + // Float + { + QWidget* floatTab = new QWidget(); + QFormLayout* floatFormLayout = new QFormLayout(floatTab); + floatFormLayout->setWidget(0, QFormLayout::LabelRole, new QLabel("Default")); + floatFormLayout->setWidget(1, QFormLayout::LabelRole, new QLabel("Min")); + floatFormLayout->setWidget(2, QFormLayout::LabelRole, new QLabel("Max")); + floatDefault = new QLineEdit("0"); + floatFormLayout->setWidget(0, QFormLayout::FieldRole, floatDefault); + floatMin = new QLineEdit("0"); + floatFormLayout->setWidget(1, QFormLayout::FieldRole, floatMin); + floatMax = new QLineEdit("1"); + floatFormLayout->setWidget(2, QFormLayout::FieldRole, floatMax); + + tabWidget->addTab(floatTab, QString("Float")); + } + + // Float + { + QWidget* vectorTab = new QWidget(); + QFormLayout* vectorFormLayout = new QFormLayout(vectorTab); + vectorFormLayout->setWidget(0, QFormLayout::LabelRole, new QLabel("Default")); + vectorFormLayout->setWidget(1, QFormLayout::LabelRole, new QLabel("Min")); + vectorFormLayout->setWidget(2, QFormLayout::LabelRole, new QLabel("Max")); + vectorDefault0 = new QLineEdit("0"); + vectorDefault1 = new QLineEdit("0"); + vectorDefault2 = new QLineEdit("0"); + QHBoxLayout* compLayout=new QHBoxLayout(); + compLayout->addWidget(vectorDefault0); + compLayout->addWidget(vectorDefault1); + compLayout->addWidget(vectorDefault2); + vectorFormLayout->setLayout(0, QFormLayout::FieldRole, compLayout); + vectorMin = new QLineEdit("0"); + vectorFormLayout->setWidget(1, QFormLayout::FieldRole, vectorMin); + vectorMax = new QLineEdit("1"); + vectorFormLayout->setWidget(2, QFormLayout::FieldRole, vectorMax); + + tabWidget->addTab(vectorTab, QString("Vector")); + } + + // Color + { + QWidget* colorTab = new QWidget(); + QFormLayout* colorLayout = new QFormLayout(colorTab); + colorWidget=new QPushButton(); + colorWidget->setFixedWidth(30); + colorWidget->setFixedWidth(30); + colorLayout->setWidget(0,QFormLayout::LabelRole,new QLabel("Color")); + colorLayout->setWidget(0,QFormLayout::FieldRole,colorWidget); + color=Qt::red; + QPixmap colorPix(30,30); + colorPix.fill(color); + colorWidget->setIcon(QIcon(colorPix)); + tabWidget->addTab(colorTab, QString("Color")); + + connect(colorWidget,SIGNAL(clicked()),this,SLOT(colorChooseClicked())); + } + + // String literal + { + QWidget* stringTab = new QWidget(); + QFormLayout* stringLayout = new QFormLayout(stringTab); + stringTypeWidget=new QComboBox(); + stringTypeWidget->addItem("string"); + stringTypeWidget->addItem("file"); + stringTypeWidget->addItem("directory"); + stringDefaultWidget=new QLineEdit(); + stringNameWidget=new QLineEdit("str1"); + + stringLayout->setWidget(0,QFormLayout::LabelRole,new QLabel("String Name")); + stringLayout->setWidget(0,QFormLayout::FieldRole,stringNameWidget); + stringLayout->setWidget(1,QFormLayout::LabelRole,new QLabel("String Type")); + stringLayout->setWidget(1,QFormLayout::FieldRole,stringTypeWidget); + stringLayout->setWidget(2,QFormLayout::LabelRole,new QLabel("String Default")); + stringLayout->setWidget(3,QFormLayout::FieldRole,stringDefaultWidget); + + tabWidget->addTab(stringTab, QString("String")); + } + + verticalLayout->addWidget(tabWidget); + + QDialogButtonBox* buttonBox = new QDialogButtonBox(); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + + verticalLayout->addWidget(buttonBox); + + + QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + tabWidget->setCurrentIndex(0); + + } + +void SeExprEdAddDialog::colorChooseClicked() +{ + color = QColorDialog::getColor(color); + if(color.isValid()) + { + QPixmap colorPix(30,30); + colorPix.fill(color); + colorWidget->setIcon(QIcon(colorPix)); + } +} + +void SeExprEdControlCollection::addControlDialog() +{ + SeExprEdAddDialog* dialog=new SeExprEdAddDialog(count,this); + if(dialog->exec()){ + QString s; + switch(dialog->tabWidget->currentIndex()){ + case 0: + s=QString("%1 = curve(%2,0,0,4,1,1,4);\n") + .arg(dialog->variableName->text()) + .arg(dialog->curveLookup->text()); + break; + case 1: + s=QString("%1 = ccurve(%2,0,[0,0,0],4,1,[1,1,1],4);\n") + .arg(dialog->variableName->text()) + .arg(dialog->colorCurveLookup->text()); + break; + case 2: + s=QString("%1 = animCurve(%2,\"constant\",\"constant\",0,\"%3\");") + .arg(dialog->variableName->text()) + .arg(dialog->animCurveLookup->text()) + .arg(dialog->animCurveLink->text()); + break; + case 3: + s=dialog->variableName->text()+" = "+dialog->intDefault->text() + +"; # "+dialog->intMin->text()+","+dialog->intMax->text()+"\n"; + break; + case 4: + s=QString("%1 = %2; # %3, %4\n").arg(dialog->variableName->text()) + .arg(dialog->floatDefault->text()) + .arg(atof(dialog->floatMin->text().toStdString().c_str()),0,'f',3) + .arg(atof(dialog->floatMax->text().toStdString().c_str()),0,'f',3); + break; + case 5: + s=QString("%1 = [%2,%3,%4]; # %5, %6\n").arg(dialog->variableName->text()) + .arg(dialog->vectorDefault0->text()) + .arg(dialog->vectorDefault1->text()) + .arg(dialog->vectorDefault2->text()) + .arg(atof(dialog->vectorMin->text().toStdString().c_str()),0,'f',3) + .arg(atof(dialog->vectorMax->text().toStdString().c_str()),0,'f',3); + break; + case 6: + s=QString("%1 = [%2,%3,%4];\n") + .arg(dialog->variableName->text()) + .arg(dialog->color.redF()) + .arg(dialog->color.greenF()) + .arg(dialog->color.blueF()); + break; + case 7: + s=QString("\"%1\" #%2 %3\n") + .arg(dialog->stringDefaultWidget->text()) + .arg(dialog->stringTypeWidget->currentText()) + .arg(dialog->stringNameWidget->text()); + break; + } + emit insertString(s.toStdString()); + } +} + +bool SeExprEdControlCollection:: +rebuildControls(const QString& expressionText,std::vector& variables) +{ + // parse a new editable expression so we can check if we need to make new controls + SeExprEdEditableExpression* newEditable=new SeExprEdEditableExpression; + newEditable->setExpr(expressionText.toStdString()); + + // check for new variables + + bool newVariables=true; + if(editableExpression && editableExpression->getVariables()==newEditable->getVariables()) newVariables=false; + if(newVariables){ + const std::vector& vars=newEditable->getVariables(); + variables.clear(); + for(size_t k=0;ksize()==0 && !editableExpression) return false; + + if(editableExpression && editableExpression->controlsMatch(*newEditable)){ + // controls match so we only need to update positions (i.e. if the user typed and shifted some controls) + editableExpression->updateString(*newEditable); + delete newEditable; + }else{ + // controls did not match + + // delete old controls + for (unsigned int i = 0; i < _controls.size(); i++){ + controlLayout->removeWidget(_controls[i]); + delete _controls[i]; + } + _linkedId=-1; + _controls.clear(); + + // swap to new editable expression + delete editableExpression; + editableExpression=newEditable; + + //build new controls + for(size_t i=0;isize();i++){ + SeExprEdEditable* editable=(*editableExpression)[i]; + SeExprEdControl* widget=0; + //std::cerr<<"looking at control "<str()<(editable)) widget=new SeExprEdNumberControl(i,x); + else if(SeExprEdVectorEditable* x=dynamic_cast(editable)) widget=new SeExprEdVectorControl(i,x); + else if(SeExprEdStringEditable* x=dynamic_cast(editable)) widget=new SeExprEdStringControl(i,x); + else if(SeExprEdCurveEditable* x=dynamic_cast(editable)) widget=new SeExprEdCurveControl(i,x); + else if(SeExprEdColorCurveEditable* x=dynamic_cast(editable)) widget=new SeExprEdCCurveControl(i,x); + else if(SeExprEdAnimCurveEditable* x=dynamic_cast(editable)){ + widget=new SeExprEdAnimCurveControl(i,x); + } + else{ + std::cerr<<"SeExpr editor logic error, cannot find a widget for the given editable"<count()-1; + if(showAddButton) insertPoint--; + controlLayout->insertWidget(insertPoint,widget); + _controls.push_back(widget); + connect(widget, SIGNAL(controlChanged(int)), SLOT(singleControlChanged(int))); + connect(widget, SIGNAL(linkColorEdited(int,QColor)), SLOT(linkColorEdited(int,QColor))); + connect(widget, SIGNAL(linkColorLink(int)), SLOT(linkColorLink(int))); + }else{ + std::cerr<<"Expr Editor Logic ERROR did not make widget"<= (int)_controls.size()) + return; + + /* Right now we only launch the anim curve editor. + * It would be better to launch them generically. */ + SeExprEdAnimCurveControl *control = dynamic_cast(_controls[idx]); + if (!control) + return; + + control->editGraphClicked(); +} + +void SeExprEdControlCollection:: +linkColorLink(int id) +{ + _linkedId=id; + for(unsigned int i=0;i<_controls.size();i++){ + _controls[i]->linkDisconnect(_linkedId); + } +} + +void SeExprEdControlCollection:: +linkColorEdited(int id,QColor color) +{ + if(id==_linkedId) + emit linkColorOutput(color); +} + + +void SeExprEdControlCollection:: +linkColorInput(QColor color) +{ + // TODO: fix + if(_linkedId<0 || _linkedId>=(int)_controls.size()) return; + _controls[_linkedId]->setColor(color); +} + +void SeExprEdControlCollection:: +updateText(const int id,QString& text) +{ + Q_UNUSED(id); + if(editableExpression) + text=QString(editableExpression->getEditedExpr().c_str()); +} + +void SeExprEdControlCollection:: +singleControlChanged(int id) +{ + emit controlChanged(id); +} + diff --git a/src/SeExprEditor/SeExprEdControlCollection.h b/src/SeExprEditor/SeExprEdControlCollection.h new file mode 100644 index 00000000..c3d123e7 --- /dev/null +++ b/src/SeExprEditor/SeExprEdControlCollection.h @@ -0,0 +1,135 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdControlCollection.h +* @brief Manages/creates a bunch of SeExprEdControls by using expression text +* @author aselle +*/ +#ifndef _SeExprEdControlCollection_ +#define _SeExprEdControlCollection_ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "SeExprEdControl.h" + +class QVBoxLayout; +class SeExprEdEditableExpression; + +/// This class is the UI for adding widgets +class SeExprEdAddDialog:public QDialog +{ + Q_OBJECT; +public: + QLineEdit *variableName; + QTabWidget *tabWidget; + QLineEdit *intDefault; + QLineEdit *intMin; + QLineEdit *intMax; + QLineEdit *floatDefault; + QLineEdit *floatMin; + QLineEdit *floatMax; + QLineEdit *vectorDefault0; + QLineEdit *vectorDefault1; + QLineEdit *vectorDefault2; + QLineEdit *vectorMin; + QLineEdit *vectorMax; + QLineEdit *curveLookup; + QLineEdit *colorCurveLookup; + QLineEdit *animCurveLookup; + QLineEdit *animCurveLink; + QColor color; + QPushButton* colorWidget; + QComboBox* stringTypeWidget; + QLineEdit* stringDefaultWidget; + QLineEdit* stringNameWidget; + + SeExprEdAddDialog(int& count,QWidget* parent=0); +private slots: + void colorChooseClicked(); + +}; + +/// Widget that holds and manages controls for a SeExpression +/// This is typically used by a SeExprEditor or a SeExprEdShortEdit widget +/// This widget also is responsible for finding all user local variables (for use in autocomplete) +class SeExprEdControlCollection:public QWidget +{ + Q_OBJECT; + + int _linkedId; + int count; + bool showAddButton; + + // holds a representation factored into the controls + SeExprEdEditableExpression* editableExpression; +public: + SeExprEdControlCollection(QWidget* parent=0,bool showAddButton=true); + ~SeExprEdControlCollection(); + +private: + // TODO: put back + std::vector _controls; + QVBoxLayout* controlLayout; +public: + /// Request new text, given taking into account control id's new values + void updateText(const int id,QString& text); + /// Rebuild the controls given the new expressionText. Return any local variables found + bool rebuildControls(const QString& expressionText,std::vector& variables); + + /// Number of controls + int numControls() { return _controls.size(); } + + void showEditor(int idx); + + /// Anim curve callback + static void setAnimCurveCallback(SeExprEdAnimCurveControl::AnimCurveCallback callback){ + SeExprEdAnimCurveControl::setAnimCurveCallback(callback); + } + +private slots: + /// When a user clicks "Add Widget" button + void addControlDialog(); + /// Notification when by a control whenever it is edited + void singleControlChanged(int id); + /// Notification by a control that a new color link is desired + void linkColorLink(int id); + /// Notification by a control that a color is edited (when it is linked) + void linkColorEdited(int id,QColor color); +signals: + /// Notification that a specific control was changed + void controlChanged(int id); + /// Gives information about when a link color was changed + void linkColorOutput(QColor color); + /// Emitted to request that a new widget string should be added to the expression + /// i.e. after "Add Widget" was used + void insertString(const std::string& controlString); +public slots: + /// Notification from outside that a linked color widget was changed + /// and should be forwarded to any linked controls + void linkColorInput(QColor color); + +}; + +#endif + + diff --git a/src/SeExprEditor/SeExprEdCurve.cpp b/src/SeExprEditor/SeExprEdCurve.cpp new file mode 100644 index 00000000..b41fb606 --- /dev/null +++ b/src/SeExprEditor/SeExprEdCurve.cpp @@ -0,0 +1,481 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdCurve.cpp +* @brief Contains PyQt4 Ramp Widget to emulate Maya's ramp widget +* @author Arthur Shek +* @version ashek 05/04/09 Initial Version +*/ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "SeExprEdCurve.h" + +void CurveScene::removeAll() +{ + _cvs.clear(); +} + + +void CurveGraphicsView::resizeEvent(QResizeEvent *event) +{ + emit resizeSignal(event->size().width(), event->size().height()); +} + + +CurveScene::CurveScene() : _curve(new T_CURVE),_width(320), _height(170), _interp(T_CURVE::kMonotoneSpline), _selectedItem(-1), _curvePoly(0), _baseRect(0), _lmb(false) +{ + rebuildCurve(); + resize(_width, _height); +} + +CurveScene::~CurveScene() +{ + delete _curve; +} + +void CurveScene::resize(const int width, const int height) +{ + // width and height already have the 8 px padding factored in + _width = width-16; + _height = height-16; + setSceneRect(-9, -7, width, height); + drawRect(); + drawPoly(); + drawPoints(); +} + +void CurveScene::rebuildCurve() +{ + delete _curve; + _curve=new T_CURVE; + for(unsigned int i=0;i<_cvs.size();i++) + _curve->addPoint(_cvs[i]._pos,_cvs[i]._val,_cvs[i]._interp); + _curve->preparePoints(); +} + + +void CurveScene::addPoint(double x, double y, const T_INTERP interp, const bool select) +{ + x=SeExpr::clamp(x,0,1); + y=SeExpr::clamp(y,0,1); + + _cvs.push_back(T_CURVE::CV(x,y,T_INTERP(interp))); + int newIndex=_cvs.size()-1; + + rebuildCurve(); + + if(select) _selectedItem = newIndex; + drawPoly(); + drawPoints(); +} + + +void CurveScene::removePoint(const int index) +{ + _cvs.erase(_cvs.begin()+index); + _selectedItem = -1; + rebuildCurve(); + + drawPoly(); + drawPoints(); + emitCurveChanged(); +} + +void CurveScene::keyPressEvent(QKeyEvent *event) +{ + if (((event->key() == Qt::Key_Backspace) || + (event->key() == Qt::Key_Delete)) && (_selectedItem >= 0)) { + // user hit delete with cv selected + removePoint(_selectedItem); + } +} + + +void CurveScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + _lmb = true; + QPointF pos = mouseEvent->scenePos(); + // get items under mouse click + QList itemList = items(pos); + if (itemList.empty()) { + _selectedItem = -1; + emit cvSelected(-1, -1, _interp); + drawPoints(); + } else if (itemList[0]->zValue() == 2) { + // getting here means we've selected a current point + const int numCircle = _circleObjects.size(); + for (int i = 0; i < numCircle; i++ ) { + QGraphicsItem *obj = _circleObjects[i]; + if (obj == itemList[0]) { + _selectedItem = i; + _interp = _cvs[i]._interp; + emit cvSelected(_cvs[i]._pos, _cvs[i]._val, _cvs[i]._interp); + } + } + drawPoints(); + } else { + // getting here means we want to create a new point + double myx=pos.x()/_width; + T_INTERP interpFromNearby=_curve->getLowerBoundCV(SeExpr::clamp(myx,0,1))._interp; + if(interpFromNearby==T_CURVE::kNone) interpFromNearby=T_CURVE::kMonotoneSpline; + + addPoint(myx, pos.y()/_height, interpFromNearby); + emitCurveChanged(); + } +} + + +void CurveScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + if (_lmb) { + QPointF point = mouseEvent->scenePos(); + if (_selectedItem >= 0) { + // clamp motion to inside curve area + double pos = SeExpr::clamp(point.x()/_width,0,1); + double val = SeExpr::clamp(point.y()/_height,0,1); + _cvs[_selectedItem]._pos=pos; + _cvs[_selectedItem]._val=val; + rebuildCurve(); + emit cvSelected(pos, val, _cvs[_selectedItem]._interp); + drawPoly(); + drawPoints(); + emitCurveChanged(); + } + } +} + + +void CurveScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + Q_UNUSED(mouseEvent); + _lmb = false; +} + +// user selected a different interpolation type, redraw +void CurveScene::interpChanged(const int interp) +{ + _interp = T_INTERP(interp); + if (_selectedItem >= 0) { + _cvs[_selectedItem]._interp=_interp; + rebuildCurve(); + drawPoly(); + emitCurveChanged(); + } +} + +// user entered a different point position, redraw +void CurveScene::selPosChanged(double posInput) +{ + if (_selectedItem >= 0) { + double pos=SeExpr::clamp(posInput,0,1); + _cvs[_selectedItem]._pos=pos; + rebuildCurve(); + drawPoly(); + drawPoints(); + emitCurveChanged(); + } +} + +// user entered a different point value, redraw +void CurveScene::selValChanged(double val) +{ + if (_selectedItem >= 0) { + val=SeExpr::clamp(val,0,1); + _cvs[_selectedItem]._val=val; + rebuildCurve(); + drawPoly(); + drawPoints(); + emitCurveChanged(); + } +} + +// return points in reverse order in order to use same parsing in editor +void CurveScene::emitCurveChanged() +{ + emit curveChanged(); +} + +// draws the base gray outline rectangle +void CurveScene::drawRect() +{ + if (_baseRect == 0) { + _baseRect = addRect(0, 0, _width, _height, QPen(Qt::black, 1.0), QBrush(Qt::gray)); + + } + _baseRect->setRect(0, 0, _width, _height); + _baseRect->setZValue(0); +} + + +// draws the poly curve representation +void CurveScene::drawPoly() +{ + if (_curvePoly == 0) { + _curvePoly = addPolygon(QPolygonF(), QPen(Qt::black, 1.0), QBrush(Qt::darkGray)); + } + + QPolygonF poly; + poly.append(QPointF(_width, 0)); + poly.append(QPointF(0, 0)); + for (int i = 0; i < 1000; i++) { + double x = i/1000.0; + poly.append(QPointF(_width*x, _height*_curve->getValue(x))); + } + poly.append(QPointF(_width, 0)); + _curvePoly->setPolygon(poly); + _curvePoly->setZValue(1); +} + + +// draws the cv points +void CurveScene::drawPoints() +{ + while (_circleObjects.size()) { + delete _circleObjects[0]; + _circleObjects.erase(_circleObjects.begin()); + } + const int numCV = _cvs.size(); + for (int i = 0; i < numCV; i++) { + const T_CURVE::CV& pt = _cvs[i]; + QPen pen; + if (i == _selectedItem) { + pen = QPen(Qt::white,1.0); + } else { + pen = QPen(Qt::black,1.0); + } + _circleObjects.push_back(addEllipse(pt._pos*_width-4, pt._val*_height-4, 8, 8, pen, QBrush())); + QGraphicsEllipseItem *circle = _circleObjects.back(); + circle->setFlag(QGraphicsItem::ItemIsMovable, true); + circle->setZValue(2); + } +} + +SeExprEdCurve::SeExprEdCurve(QWidget* parent, QString pLabel, QString vLabel, QString iLabel, + bool expandable) : QWidget(parent), _scene(0), _selPosEdit(0), _selValEdit(0), _interpComboBox(0) +{ + Q_UNUSED(iLabel); + QHBoxLayout *mainLayout = new QHBoxLayout(); + mainLayout->setSpacing(2); + mainLayout->setMargin(4); + + QWidget *edits = new QWidget; + QVBoxLayout *editsLayout = new QVBoxLayout; + editsLayout->setAlignment(Qt::AlignTop); + editsLayout->setSpacing(0); + editsLayout->setMargin(0); + edits->setLayout(editsLayout); + + QWidget *selPos = new QWidget; + QHBoxLayout *selPosLayout = new QHBoxLayout; + selPosLayout->setSpacing(1); + selPosLayout->setMargin(1); + selPos->setLayout(selPosLayout); + _selPosEdit = new QLineEdit; + QDoubleValidator *posValidator = new QDoubleValidator(0.0,1.0,6,_selPosEdit); + _selPosEdit->setValidator(posValidator); + int editwidth = QFontMetrics(font()).width("9.999")+8; + _selPosEdit->setFixedWidth(editwidth); + _selPosEdit->setFixedHeight(20); + selPosLayout->addStretch(50); + QLabel *posLabel; + if (pLabel.isEmpty()) { + posLabel = new QLabel("Selected Position: "); + } else { + posLabel = new QLabel(pLabel); + } + selPosLayout->addWidget(posLabel); + selPosLayout->addWidget(_selPosEdit); + + QWidget *selVal = new QWidget; + QBoxLayout *selValLayout = new QHBoxLayout; + selValLayout->setSpacing(1); + selValLayout->setMargin(1); + selVal->setLayout(selValLayout); + _selValEdit = new QLineEdit; + QDoubleValidator *valValidator = new QDoubleValidator(0.0,1.0,6,_selValEdit); + _selValEdit->setValidator(valValidator); + _selValEdit->setFixedWidth(editwidth); + _selValEdit->setFixedHeight(20); + selValLayout->addStretch(50); + QLabel *valLabel; + if (vLabel.isEmpty()) { + valLabel = new QLabel("Selected Value: "); + } else { + valLabel = new QLabel(vLabel); + } + selValLayout->addWidget(valLabel); + selValLayout->addWidget(_selValEdit); + + _interpComboBox = new QComboBox; + _interpComboBox->addItem("None"); + _interpComboBox->addItem("Linear"); + _interpComboBox->addItem("Smooth"); + _interpComboBox->addItem("Spline"); + _interpComboBox->addItem("MSpline"); + _interpComboBox->setCurrentIndex(4); + _interpComboBox->setFixedWidth(70); + _interpComboBox->setFixedHeight(20); + + + editsLayout->addWidget(selPos); + editsLayout->addWidget(selVal); + editsLayout->addWidget(_interpComboBox); + + QFrame *curveFrame = new QFrame; + curveFrame->setFrameShape(QFrame::Panel); + curveFrame->setFrameShadow(QFrame::Sunken); + curveFrame->setLineWidth(1); + QHBoxLayout *curveFrameLayout = new QHBoxLayout; + curveFrameLayout->setMargin(0); + CurveGraphicsView *curveView = new CurveGraphicsView; + curveView->setFrameShape(QFrame::Panel); + curveView->setFrameShadow(QFrame::Sunken); + curveView->setLineWidth(1); + curveView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + curveView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + _scene = new CurveScene; + curveView->setScene(_scene); + curveView->setTransform(QTransform().scale(1, -1)); + curveView->setRenderHints(QPainter::Antialiasing); + curveFrameLayout->addWidget(curveView); + curveFrame->setLayout(curveFrameLayout); + + mainLayout->addWidget(edits); + mainLayout->addWidget(curveFrame); + if(expandable){ + QPushButton* expandButton=new QPushButton(">"); + expandButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding); + expandButton->setFixedWidth(15); + mainLayout->addWidget(expandButton); + // open a the detail widget when clicked + connect(expandButton, SIGNAL(clicked()), this, SLOT(openDetail())); + } + mainLayout->setStretchFactor(curveFrame,100); + setLayout(mainLayout); + + // SIGNALS + + // when a user selects a cv, update the fields on left + connect(_scene, SIGNAL(cvSelected(double, double, T_INTERP)), this, SLOT(cvSelectedSlot(double, double, T_INTERP))); + // when a user selects a different interp, the curve has to redraw + connect(_interpComboBox, SIGNAL(activated(int)), _scene, SLOT(interpChanged(int))); + // when a user types a different position, the curve has to redraw + connect(_selPosEdit, SIGNAL(returnPressed()), this, SLOT(selPosChanged())); + connect(this, SIGNAL(selPosChangedSignal(double)), _scene, SLOT(selPosChanged(double))); + // when a user types a different value, the curve has to redraw + connect(_selValEdit, SIGNAL(returnPressed()), this, SLOT(selValChanged())); + connect(this, SIGNAL(selValChangedSignal(double)), _scene, SLOT(selValChanged(double))); + // when the widget is resized, resize the curve widget + connect(curveView, SIGNAL(resizeSignal(int, int)), _scene, SLOT(resize(int, int))); + +} + + +// CV selected, update the user interface fields. +void SeExprEdCurve::cvSelectedSlot(double pos, double val, T_INTERP interp) +{ + QString posStr; + if (pos >= 0.0) posStr.setNum(pos, 'f', 3); + _selPosEdit->setText(posStr); + QString valStr; + if (val >= 0.0) valStr.setNum(val, 'f', 3); + _selValEdit->setText(valStr); + _interpComboBox->setCurrentIndex(interp); +} + + +// User entered new position, round and send signal to redraw curve. +void SeExprEdCurve::selPosChanged() +{ + double pos = QString(_selPosEdit->text()).toDouble(); + _selPosEdit->setText(QString("%1").arg(pos, 0, 'f', 3)); + emit selPosChangedSignal(pos); +} + + +// User entered new value, round and send signal to redraw curve. +void SeExprEdCurve::selValChanged() +{ + double val = QString(_selValEdit->text()).toDouble(); + val=SeExpr::clamp(val,0,1); + _selValEdit->setText(QString("%1").arg(val, 0, 'f', 3)); + emit selValChangedSignal(val); +} + +void SeExprEdCurve::openDetail() +{ + QDialog* dialog=new QDialog(); + dialog->setMinimumWidth(1024); + dialog->setMinimumHeight(400); + SeExprEdCurve* curve=new SeExprEdCurve(0,"","","",false); + + // copy points into new data + const std::vector& data=_scene->_cvs; + typedef std::vector::const_iterator ITERATOR; + for(ITERATOR i=data.begin();i!=data.end();++i) + curve->addPoint(i->_pos,i->_val,i->_interp); + + QVBoxLayout* layout=new QVBoxLayout(); + dialog->setLayout(layout); + layout->addWidget(curve); + QDialogButtonBox* buttonbar=new QDialogButtonBox(); + buttonbar->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + connect(buttonbar,SIGNAL(accepted()),dialog,SLOT(accept())); + connect(buttonbar,SIGNAL(rejected()),dialog,SLOT(reject())); + layout->addWidget(buttonbar); + + if(dialog->exec()==QDialog::Accepted){ + // copy points back from child + _scene->removeAll(); + const std::vector& dataNew=curve->_scene->_cvs; + typedef std::vector::const_iterator ITERATOR; + for(ITERATOR i=dataNew.begin();i!=dataNew.end();++i) + addPoint(i->_pos,i->_val,i->_interp); + _scene->emitCurveChanged(); + } + + + if(dialog->exec()==QDialog::Accepted){ + // copy points back from child + _scene->removeAll(); + const std::vector& dataNew=curve->_scene->_cvs; + typedef std::vector::const_iterator ITERATOR; + for(ITERATOR i=dataNew.begin();i!=dataNew.end();++i) + addPoint(i->_pos,i->_val,i->_interp); + _scene->emitCurveChanged(); + } +} + +void SeExprEdCurve::addPoint(const double x, const double y, T_INTERP interp, const bool select) +{ + _scene->addPoint(x, y, interp, select); +} + diff --git a/src/SeExprEditor/SeExprEdCurve.h b/src/SeExprEditor/SeExprEdCurve.h new file mode 100644 index 00000000..72ecd475 --- /dev/null +++ b/src/SeExprEditor/SeExprEdCurve.h @@ -0,0 +1,150 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdCurve.h +* @brief Contains PyQt4 Ramp Widget to emulate Maya's ramp widget +* @author Arthur Shek +* @version ashek 05/04/09 Initial Version +*/ +#ifndef _SeExprEdCurve_h_ +#define _SeExprEdCurve_h_ + + +#include + +#include +#include +#include +#include +#include + +#include + +/* + This class overrides QGraphicsView so we can get resize events +*/ +class CurveGraphicsView : public QGraphicsView +{ + Q_OBJECT +public: + CurveGraphicsView() { + setTransformationAnchor(QGraphicsView::NoAnchor); + setResizeAnchor(QGraphicsView::NoAnchor); + } + ~CurveGraphicsView() {} + + virtual void resizeEvent(QResizeEvent *event); + +signals: + void resizeSignal(int width, int height); +}; + +/* + This class overrides QGraphicsScene so we can handle mouse + press, drag and keyboard events +*/ +class CurveScene : public QGraphicsScene +{ + Q_OBJECT + + typedef SeExpr::SeCurve T_CURVE; + typedef T_CURVE::InterpType T_INTERP ; +public: + CurveScene(); + ~CurveScene(); + + void addPoint(double x, double y, const T_INTERP interp, const bool select=true); + + void removePoint(const int index); + void removeAll(); + + virtual void keyPressEvent(QKeyEvent *event); + + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent); + + void drawRect(); + + void drawPoly(); + + void drawPoints(); + + void emitCurveChanged(); + + void rebuildCurve(); + + std::vector _cvs; // unsorted cvs + + friend class SeExprEdCurve; + +private: + T_CURVE* _curve; +public slots: + void interpChanged(const int interp); + void selPosChanged(double pos); + void selValChanged(double val); + void resize(const int width, const int height); + +signals: + void cvSelected(double x, double y, T_INTERP interp); + void curveChanged(); + +private: + + int _width; + int _height; + T_INTERP _interp; + std::vector _circleObjects; + int _selectedItem; + QGraphicsPolygonItem *_curvePoly; + QGraphicsRectItem *_baseRect; + bool _lmb; +}; + +class SeExprEdCurve : public QWidget +{ + Q_OBJECT + + typedef SeExpr::SeCurve T_CURVE; + typedef T_CURVE::InterpType T_INTERP ; + +public: + SeExprEdCurve(QWidget* parent = 0, QString pLabel = "", QString vLabel = "", QString iLabel = "", + bool expandable=true); + ~SeExprEdCurve() {} + + // Convenience Functions + void addPoint(const double x, const double y, const T_INTERP interp, bool select=false); + + CurveScene *_scene; + +public slots: + void cvSelectedSlot(double pos, double val, T_INTERP interp); + void selPosChanged(); + void selValChanged(); + void openDetail(); + +signals: + void selPosChangedSignal(double pos); + void selValChangedSignal(double val); + +private: + QLineEdit *_selPosEdit; + QLineEdit *_selValEdit; + QComboBox *_interpComboBox; +}; +#endif diff --git a/src/SeExprEditor/SeExprEdDialog.cpp b/src/SeExprEditor/SeExprEdDialog.cpp new file mode 100644 index 00000000..f8e6a555 --- /dev/null +++ b/src/SeExprEditor/SeExprEdDialog.cpp @@ -0,0 +1,345 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdDialog.cppp +* @brief A basic editor/browser/previewer for expression editing +* @author jlacewel +*/ + +#include "SeExprEdBrowser.h" +#include "SeExprEdGrapher2d.h" +#include "SeExprEdDialog.h" +#include "SeExprEdControlCollection.h" + +#include +#include +#include +#include +#include + +#ifdef SEEXPR_USE_PF +# include +#endif + +#define P3D_CONFIG_ENVVAR "P3D_CONFIG_PATH" + + +SeExprEdDialog::SeExprEdDialog(QWidget* parent) + :QDialog(parent), _currentEditorIdx(0) +{ + this->setMinimumWidth(600); + QVBoxLayout* rootLayout=new QVBoxLayout(0); + rootLayout->setMargin(2); + this->setLayout(rootLayout); + + showEditorTimer = new QTimer(); + connect(showEditorTimer, SIGNAL(timeout()), SLOT(_showEditor())); + + QSplitter* vsplitter=new QSplitter( Qt::Vertical, this ); + rootLayout->addWidget(vsplitter); + + QTabWidget* topTabWidget=new QTabWidget(); + vsplitter->addWidget(topTabWidget); + + QWidget* previewLibraryWidget=new QWidget(); + QHBoxLayout* previewLibraryLayout=new QHBoxLayout(); + previewLibraryWidget->setLayout(previewLibraryLayout); + topTabWidget->addTab(previewLibraryWidget,"Preview / Library"); + + QWidget* bottomWidget=new QWidget(); + vsplitter->addWidget(bottomWidget); + QVBoxLayout* bottomLayout=new QVBoxLayout(); + bottomLayout->setMargin(1); + bottomWidget->setLayout(bottomLayout); + + // setup preview + QWidget* leftWidget=new QWidget(); + leftWidget->setFixedWidth(450); + QVBoxLayout* leftLayout=new QVBoxLayout(); + leftLayout->setMargin(0); + leftWidget->setLayout(leftLayout); + QHBoxLayout* previewLayout=new QHBoxLayout(); + grapher=new SeExprEdGrapherWidget(this, 200, 200); + previewLayout->addWidget(grapher,0); + previewCommentLabel=new QLabel(); + previewLayout->addWidget(previewCommentLabel,1,Qt::AlignLeft | Qt::AlignTop); + leftLayout->addLayout(previewLayout); + previewLibraryLayout->addWidget(leftWidget); + + // setup button bar + //QWidget* buttonBarWidget=new QWidget(); + QHBoxLayout* buttonBarLayout = new QHBoxLayout(); + //buttonBarWidget->setLayout(buttonBarLayout); + buttonBarLayout->setMargin(1); + previewButton=new QPushButton("Preview"); + buttonBarLayout->addWidget(previewButton); + saveButton = new QPushButton("Save"); + buttonBarLayout->addWidget(saveButton); + saveAsButton = new QPushButton("Save As"); + buttonBarLayout->addWidget(saveAsButton); + saveLocalButton = new QPushButton("Save Local"); + saveLocalButton->setEnabled(false); + buttonBarLayout->addWidget(saveLocalButton); + clearButton = new QPushButton("Clear"); + buttonBarLayout->addWidget(clearButton); + bottomLayout->addLayout(buttonBarLayout); + + controls = new SeExprEdControlCollection(); + + // controls + QScrollArea* scrollArea=new QScrollArea(); + scrollArea->setWidget(controls); + //scrollArea->setWidget(new QLabel("test\nweird\nfds\nfdsahsha\nfsdajdlsa\nfasdjjhsafd\nfasdhjdfsa\nfdasjdfsha")); + scrollArea->setFocusPolicy(Qt::NoFocus); + scrollArea->setMinimumHeight(100); + scrollArea->setFixedWidth(450); + scrollArea->setWidgetResizable(true); + leftLayout->addWidget(scrollArea,1); + + // make button bar + editor=new SeExprEditor(this,controls); + connect(editor,SIGNAL(apply()),SLOT(applyExpression())); + connect(editor,SIGNAL(preview()),SLOT(applyExpression())); + connect(grapher,SIGNAL(preview()),SLOT(applyExpression())); + bottomLayout->addWidget(editor); + + // make expression library browser + browser=new SeExprEdBrowser(0,editor); + previewLibraryLayout->addWidget(browser); + + // dialog buttons + QHBoxLayout* buttonLayout = new QHBoxLayout(0); + buttonLayout->addItem(new QSpacerItem(0,0, QSizePolicy::MinimumExpanding, + QSizePolicy::Minimum)); + applyButton=new QPushButton("Apply"); + buttonLayout->addWidget(applyButton); + acceptButton=new QPushButton("Accept"); + buttonLayout->addWidget(acceptButton); + cancelButton = new QPushButton("Cancel"); + buttonLayout->addWidget(cancelButton); + connect(applyButton, SIGNAL(clicked()), this, SLOT(verifiedApply())); + connect(acceptButton, SIGNAL(clicked()), this, SLOT(verifiedAccept())); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + rootLayout->addLayout(buttonLayout); + + setupHelp(topTabWidget); + + // connect buttons + connect(previewButton,SIGNAL(clicked()),SLOT(applyExpression())); + connect(clearButton, SIGNAL(clicked()), SLOT(clearExpression())); + connect(saveButton, SIGNAL(clicked()), browser,SLOT(saveExpression())); + connect(saveAsButton, SIGNAL(clicked()), browser,SLOT(saveExpressionAs())); + connect(saveLocalButton, SIGNAL(clicked()), browser,SLOT(saveLocalExpressionAs())); +} + +void SeExprEdDialog::showEditor(int idx) +{ + _currentEditorIdx = idx; + showEditorTimer->setSingleShot(true); + showEditorTimer->start(); +} + +void SeExprEdDialog::_showEditor() +{ + controls->showEditor(_currentEditorIdx); +} + +int SeExprEdDialog::exec() +{ + // populate the expressions + browser->getExpressionDirs(); + browser->expandAll(); + return QDialog::exec(); +} + +void SeExprEdDialog::keyPressEvent(QKeyEvent* event) +{ + if(event->key()==Qt::Key_Escape) return; + return QDialog::keyPressEvent(event); +} + +void SeExprEdDialog::verifiedApply() +{ + applyExpression(); + if(grapher->expr.isValid()) + { + emit expressionApplied(); + } + else + { + QMessageBox msgBox; + msgBox.setText("Your expression had possible errors."); + msgBox.setInformativeText("Do you want to accept your expression anyways?"); + QPushButton* okButton = msgBox.addButton("OK", QMessageBox::RejectRole); + msgBox.addButton("Cancel", QMessageBox::AcceptRole); + int ret = msgBox.exec(); + Q_UNUSED(ret); + if(msgBox.clickedButton() == okButton) + emit expressionApplied(); + } +} + +void SeExprEdDialog::verifiedAccept() +{ + applyExpression(); + if(grapher->expr.isValid()){ + accept(); + }else{ + QMessageBox msgBox; + msgBox.setText("Your expression had possible errors."); + msgBox.setInformativeText("Do you want to accept your expression anyways?"); + QPushButton* okButton=msgBox.addButton("OK",QMessageBox::RejectRole); + msgBox.addButton("Cancel",QMessageBox::AcceptRole); + int ret = msgBox.exec(); + Q_UNUSED(ret); + if(msgBox.clickedButton()==okButton) accept(); + } +} + +void SeExprEdDialog::setupHelp(QTabWidget* tab) +{ + QWidget* browserspace = new QWidget(tab); + helpBrowser = new QTextBrowser(browserspace); + tab->addTab(browserspace, "Help"); +#ifdef SEEXPR_USE_PF + // TODO: Janet fix this! + char *path = pf_find_first("share/doc/SeExpr/SeExpressions.html"); +#else + char *path = (char *)"/usr/local/share/doc/SeExpr/SeExpressions.html"; +#endif + if (path) { + QString sheet="body {background-color: #eeeeee; color: #000000;} \na {color: #3333ff; text-decoration: none;}\n"; + helpBrowser->document()->setDefaultStyleSheet(sheet); + helpBrowser->setSource(QString(path)); +#ifdef SEEXPR_USE_PF + free(path); +#endif + } + + QPushButton* backPb = new QPushButton("Back"); + //backPb->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowLeft)); + backPb->setEnabled(false); + QPushButton* forwardPb = new QPushButton("Forward"); + // forwardPb->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowRight)); + forwardPb->setEnabled(false); + + QVBoxLayout * helpLayout = new QVBoxLayout(browserspace); + QHBoxLayout * helpPbLayout = new QHBoxLayout; + helpLayout->addLayout(helpPbLayout); + helpPbLayout->addWidget(backPb); + helpPbLayout->addWidget(forwardPb); + //helpPbLayout->addItem(new QSpacerItem(0,0, QSizePolicy::MinimumExpanding, + // QSizePolicy::Minimum)); + QHBoxLayout* findBar=new QHBoxLayout(); + helpPbLayout->addWidget(new QLabel("Find"), /*stretch*/ false); + helpFindBox=new QLineEdit; + helpPbLayout->addWidget(helpFindBox, /*stretch*/ false); + connect(helpFindBox,SIGNAL(returnPressed()),this,SLOT(findNextInHelp())); + QPushButton* nextButton=new QPushButton("Find Next"); + QPushButton* prevButton=new QPushButton("Find Prev"); + helpPbLayout->addWidget(nextButton, /*stretch*/ false); + helpPbLayout->addWidget(prevButton, /*stretch*/ false); + connect(nextButton,SIGNAL(clicked()),this,SLOT(findNextInHelp())); + connect(prevButton,SIGNAL(clicked()),this,SLOT(findPrevInHelp())); + helpPbLayout->addLayout(findBar, /*stretch*/ false); + helpLayout->addWidget(helpBrowser, /*stretch*/ true); + helpBrowser->setMinimumHeight(120); + + // wire up help browser forward/back buttons + connect(backPb, SIGNAL(clicked()), helpBrowser, SLOT(backward())); + connect(forwardPb, SIGNAL(clicked()), helpBrowser, SLOT(forward())); + connect(helpBrowser, SIGNAL(backwardAvailable(bool)), backPb, SLOT(setEnabled(bool))); + connect(helpBrowser, SIGNAL(forwardAvailable(bool)), forwardPb, SLOT(setEnabled(bool))); + +} + +void SeExprEdDialog::findHelper(QTextDocument::FindFlags flags){ + QTextDocument* doc=helpBrowser->document(); + if(prevFind!=helpFindBox->text()){ + prevFind=helpFindBox->text(); + helpBrowser->setTextCursor(QTextCursor(doc)); + } + QTextCursor blah=doc->find(helpFindBox->text(),helpBrowser->textCursor(),flags); + helpBrowser->setTextCursor(blah); +} + +void SeExprEdDialog::findNextInHelp() +{ + findHelper(0); +} + +void SeExprEdDialog::findPrevInHelp(){ + findHelper(QTextDocument::FindBackward); +} + +void SeExprEdDialog::applyExpression() +{ + editor->clearErrors(); + // set new expression + grapher->expr.setExpr(editor->getExpr()); + grapher->update(); + + // set the label widget to mention that variables will not be previewed + bool empty=true; + if(grapher->expr.varmap.size()>0){ + std::stringstream s; + s<<"Variables not supported in preview (assumed zero):
"; + int count=0; + for(SeExprEdExpression::VARMAP::iterator i=grapher->expr.varmap.begin(); + i!=grapher->expr.varmap.end();++i){ + count++; + s<<"$"<first<<" "; + if(count%4==0) s<<"
"; + } + previewCommentLabel->setText(s.str().c_str()); + empty=false; + }else previewCommentLabel->setText(""); + // set the label widget to mention that variables will not be previewed + if(grapher->expr.funcmap.size()>0){ + std::stringstream s; + s<<"Functions not supported in preview (assumed zero):
"; + int count=0; + for(SeExprEdExpression::FUNCMAP::iterator i=grapher->expr.funcmap.begin(); + i!=grapher->expr.funcmap.end();++i){ + count++; + s<<""<first<<"() "; + if(count%4==0) s<<"
"; + } + previewCommentLabel->setText(s.str().c_str()); + empty=false; + } + if(empty) previewCommentLabel->setText(""); + + // put errors into editor module + bool valid=grapher->expr.isValid(); + if(!valid){ + const std::vector & errors=grapher->expr.getErrors(); + for(unsigned int i=0;iaddError(errors[i].startPos,errors[i].endPos,errors[i].error); + } + editor->nextError(); + } +} + +void SeExprEdDialog::clearExpression() +{ + browser->clearSelection(); + editor->setExpr("",false); + grapher->expr.setExpr(""); + grapher->update(); +} + + diff --git a/src/SeExprEditor/SeExprEdDialog.h b/src/SeExprEditor/SeExprEdDialog.h new file mode 100644 index 00000000..6cec2209 --- /dev/null +++ b/src/SeExprEditor/SeExprEdDialog.h @@ -0,0 +1,111 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdDialog.h +* @brief A basic editor/browser/previewer for expression editing +* @author jlacewel +*/ +#ifndef _MY_EXPR_EDITOR_H +#define _MY_EXPR_EDITOR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include + +#include +#include + +#include "SeExprEditor.h" + + +class SeExprEdGrapherWidget; +class SeExprEdBrowser; +class QTabWidget; + +class SeExprEdDialog:public QDialog +{ + Q_OBJECT + +public: + SeExprEditor* editor; + SeExprEdBrowser* browser; +private: + SeExprEdGrapherWidget* grapher; + QLabel* previewCommentLabel; + QPushButton* acceptButton; + QPushButton* cancelButton; + SeExprEdControlCollection* controls; + + QPushButton *applyButton,*previewButton,*saveButton,*saveAsButton; + QPushButton *saveLocalButton,*clearButton; + QLineEdit* helpFindBox; + QTimer* showEditorTimer; + QTextBrowser* helpBrowser; + QTextCursor cursor; + QString prevFind; + int _currentEditorIdx; +public: + SeExprEdDialog(QWidget* parent); + + std::string getExpressionString() + { + return editor->getExpr(); + } + + void setExpressionString(const std::string& str) + { + clearExpression(); + editor->setExpr(str, /*apply*/ true); + } + + int exec(); + + // Show the Nth editor dialog + void showEditor(int idx); + +private: + void setupHelp(QTabWidget* tab); + +protected: + void keyPressEvent(QKeyEvent* event); + void findHelper(QTextDocument::FindFlags flags); + +signals: + void expressionApplied(); +private slots: + void verifiedApply(); + void verifiedAccept(); + void findNextInHelp(); + void findPrevInHelp(); + void _showEditor(); +public slots: + + void applyExpression(); + + void clearExpression(); + +}; + +#endif diff --git a/src/SeExprEditor/SeExprEdEditable.h b/src/SeExprEditor/SeExprEdEditable.h new file mode 100644 index 00000000..6b8081c0 --- /dev/null +++ b/src/SeExprEditor/SeExprEdEditable.h @@ -0,0 +1,309 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdEditable.h +* @author Andrew Selle +*/ +#ifndef __SeExprEdEditable__ +#define __SeExprEdEditable__ +#include +#include +#include +#include +#include +#include +#ifdef SEEXPR_USE_ANIMLIB +# include +# include +#endif +inline void printVal(std::stringstream& stream,double v){stream<");} + virtual void appendString(std::stringstream& stream) const=0; + virtual bool controlsMatch(const SeExprEdEditable&) const=0; + +}; + + +struct SeExprEdNumberEditable:public SeExprEdEditable +{ + double v; + double min,max; + bool isInt; + SeExprEdNumberEditable(const std::string& name,int startPos,int endPos,double val) + :SeExprEdEditable(name,startPos,endPos),v(val),min(0),max(1),isInt(false) + {} + + bool parseComment(const std::string& comment){ + if (comment.find('.') != std::string::npos || comment.find('e') != std::string::npos) + { + float fmin,fmax; + if (sscanf(comment.c_str(),"#%f,%f",&fmin,&fmax)==2) + { + min=fmin; + max=fmax; + isInt=false; + return true; + } + } + int imin,imax; + if (sscanf(comment.c_str(),"#%d,%d",&imin,&imax)==2) + { + min=imin; + max=imax; + isInt=true; + return true; + } + return true; + } + std::string str() const{ + std::stringstream s; + s<(&other)){ + return min==o->min && max==o->max && v==o->v && isInt==o->isInt && name==o->name; + }else return false; + } + +}; + + +struct SeExprEdVectorEditable:public SeExprEdEditable +{ + SeVec3d v; + double min,max; + bool isColor; + SeExprEdVectorEditable(const std::string& name,int startPos,int endPos,const SeVec3d& val) + :SeExprEdEditable(name,startPos,endPos),v(val),min(0),max(1),isColor(true) + {} + + bool parseComment(const std::string& comment){ + float fmin,fmax; + int numParsed=sscanf(comment.c_str(),"#%f,%f",&fmin,&fmax); + if(numParsed==2){ + isColor=false; + min=fmin; + max=fmax; + } + return true; + } + std::string str() const{ + std::stringstream s; + s<(&other)){ + return min==o->min && max==o->max && v==o->v && name==o->name; + }else return false; + } + +}; + +struct SeExprEdStringEditable:public SeExprEdEditable +{ + std::string v; + std::string type; + SeExprEdStringEditable(int startPos,int endPos,const std::string& val) + :SeExprEdEditable("unknown",startPos,endPos),v(val) + {} + + bool parseComment(const std::string& comment){ + char namebuf[1024],typebuf[1024]; + int parsed=sscanf(comment.c_str(),"#%s %s",typebuf,namebuf); + if(parsed==2){ + name=namebuf; + type=typebuf; + return true; + }else{ + return false; + } + } + + void appendString(std::stringstream& stream) const{ + // TODO: escape strs + stream<<"\""<(&other)){ + // TODO: fix this +// return cvs==o->cvs && name==o->name; + UNUSED(o); + return false; + }else return false; + } + +}; +typedef SeExprEdGenericCurveEditable SeExprEdColorCurveEditable; +typedef SeExprEdGenericCurveEditable SeExprEdCurveEditable; + + +struct SeExprEdAnimCurveEditable:public SeExprEdEditable +{ + std::string name; + int startPos,endPos; +#ifdef SEEXPR_USE_ANIMLIB + animlib::AnimCurve curve; +#endif + std::string link; + std::string animationSystemCurve; + std::string newText; + + SeExprEdAnimCurveEditable(const std::string& name,int startPos,int endPos) + :SeExprEdEditable(name,startPos,endPos) +#ifdef SEEXPR_USE_ANIMLIB + ,curve(animlib::AnimAttrID()) +#endif + {} + + ~SeExprEdAnimCurveEditable(){} // must have this to ensure destruction + + bool parseComment(const std::string& comment){ + animationSystemCurve=comment; + return true; + } + std::string str() const{ + std::stringstream s; + s<0) stream<(&other)){ + // TODO: fix this +// return cvs==o->cvs && name==o->name; + UNUSED(o); + return false; + }else return false; + } + +}; + +#endif + + + + + + + + + + + + diff --git a/src/SeExprEditor/SeExprEdEditableExpression.cpp b/src/SeExprEditor/SeExprEdEditableExpression.cpp new file mode 100644 index 00000000..5ff4b066 --- /dev/null +++ b/src/SeExprEditor/SeExprEdEditableExpression.cpp @@ -0,0 +1,114 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include "SeExprEdEditable.h" +#include "SeExprEdEditableExpression.h" +#include + +bool SeExprParse(std::vector& literals,std::vector& variables, + std::vector >& comments,const char* str); + + +SeExprEdEditableExpression::SeExprEdEditableExpression() +{} + +SeExprEdEditableExpression::~SeExprEdEditableExpression() +{ + cleanup(); +} + +void SeExprEdEditableExpression:: +setExpr(const std::string& expr) +{ + // get rid of old data + cleanup(); + + // run parser + _expr=expr; + std::vector > comments; + SeExprParse(_editables,_variables,comments,_expr.c_str()); + + for(Editables::iterator it=_editables.begin();it!=_editables.end();){ + SeExprEdEditable& literal=**it; + int endPos=literal.endPos; + std::string comment=""; + for(size_t ci=0;ci=endPos){ + // check to make sure there is no newlines between end of editable and comment + size_t pos=_expr.find('\n',endPos); + if(pos==std::string::npos || pos>=(size_t)comments[ci].second){ + comment=_expr.substr(comments[ci].first,comments[ci].second-comments[ci].first); + break; + } + } + } + bool keepEditable=literal.parseComment(comment); + if(!keepEditable){ // TODO: this is potentially quadratic if we remove a bunch + delete &literal; + it=_editables.erase(it); + }else{ + ++it; + } + } +} + +void SeExprEdEditableExpression::cleanup() +{ + for(size_t i=0;i<_editables.size();i++) delete _editables[i]; + _editables.clear(); + _variables.clear(); + +} + +std::string SeExprEdEditableExpression::getEditedExpr() const +{ + int offset=0; + std::stringstream stream; + for(size_t i=0,sz=_editables.size();i +#include + +class SeExprEdEditable; + +/// Factors a SeExpr into an editable expression with controls (i.e. value boxes, curve boxes) +class SeExprEdEditableExpression{ + std::string _expr; // original full expression + typedef std::vector Editables; + std::vector _editables; // control that can edit the expression + std::vector _variables; +public: + SeExprEdEditableExpression(); + ~SeExprEdEditableExpression(); + + /// Set's expressions and parses it into "control editable form" + void setExpr(const std::string& expr); + + /// Return a reconstructed expression using all the editable's current values + std::string getEditedExpr() const; + + /// Check if the other editable expression has editables that all match i.e. the controls are same + bool controlsMatch(const SeExprEdEditableExpression& other) const; + + /// Update the string refered to into the controls (this is only valid if controlsmatch) + void updateString(const SeExprEdEditableExpression& other); + + /// Access an editable parameter + SeExprEdEditable* operator[](const int i){return _editables[i];} + + /// Return the count of editable parameters + size_t size() const{return _editables.size();} + + /// Get list of commentsø + const std::vector& getVariables() const{return _variables;} +private: + /// clean memeory + void cleanup(); +}; + +#endif diff --git a/src/SeExprEditor/SeExprEdExpression.cpp b/src/SeExprEditor/SeExprEdExpression.cpp new file mode 100644 index 00000000..3d6f47dd --- /dev/null +++ b/src/SeExprEditor/SeExprEdExpression.cpp @@ -0,0 +1,73 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdExpression.cpp +* @brief A basic expression context for the expression previewer +* @author aselle +*/ + +#include "SeExprEdExpression.h" + +SeExprEdExpression::SeExprEdExpression(const std::string& expr,bool vec) + :SeExpression(expr,vec),dummyFunc(dummyFuncX,0,16) +{} + +SeExprEdExpression::~SeExprEdExpression() +{ + clearVars(); +} + +template void deleteAndClear(T_MAP& map){ + for(typename T_MAP::iterator i=map.begin();i!=map.end();++i) delete i->second; + map.clear(); +} + +void SeExprEdExpression::clearVars() +{ + deleteAndClear(varmap); + funcmap.clear(); +} + +void SeExprEdExpression::setExpr(const std::string& str) +{ + clearVars(); + SeExpression::setExpr(str); +} + +SeExprVarRef* SeExprEdExpression::resolveVar(const std::string& name) const +{ + if(name=="u") return &u; + else if(name=="v") return &v; + else if(name=="P") return &P; + else{ + // make a variable to resolve any unknown + VARMAP::iterator i=varmap.find(name); + if(i!=varmap.end()) return i->second; + else{ + varmap[name]=new VectorRef(); + return varmap[name]; + } + } +} + +SeExprFunc* SeExprEdExpression::resolveFunc(const std::string& name) const +{ + // check if it is builtin so we get proper behavior + if(SeExprFunc::lookup(name)) return 0; + + funcmap[name]=true; + return &dummyFunc; +} diff --git a/src/SeExprEditor/SeExprEdExpression.h b/src/SeExprEditor/SeExprEdExpression.h new file mode 100644 index 00000000..d753844a --- /dev/null +++ b/src/SeExprEditor/SeExprEdExpression.h @@ -0,0 +1,92 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdExpression.h +* @brief A basic expression context for the expression previewer +* @author aselle +*/ + +#ifndef SeExprEdExpression_h +#define SeExprEdExpression_h + +#include +#include +#include +#include +#include + +class SeExprEdExpression : public SeExpression +{ + public: + struct ScalarRef : public SeExprScalarVarRef { + double value; + ScalarRef() + : value(0.0) {} + virtual void eval(const SeExprVarNode* node, SeVec3d& result) { + UNUSED(node); + result = value; + } + }; + + struct VectorRef : public SeExprVectorVarRef { + SeVec3d value; + VectorRef() + : value(0.0) {} + virtual void eval(const SeExprVarNode* node, SeVec3d& result) { + UNUSED(node); + result = value; + } + }; + + struct DummyFuncX:SeExprFuncX + { + DummyFuncX() + :SeExprFuncX(true) + {} + + bool prep(SeExprFuncNode* node,bool wantVec) + { + bool valid=true; + for(int i=0;inumChildren();i++){ + if(!node->isStrArg(i)) + valid&=node->child(i)->prep(wantVec); + } + return true;} + void eval(const SeExprFuncNode* node,SeVec3d& result) const + {UNUSED(node); result=SeVec3d();} + } dummyFuncX; + mutable SeExprFunc dummyFunc; + + mutable ScalarRef u; + mutable ScalarRef v; + mutable VectorRef P; + + typedef std::map VARMAP; + mutable VARMAP varmap; + typedef std::map FUNCMAP; + mutable FUNCMAP funcmap; + + SeExprEdExpression(const std::string& expr, bool vec); + virtual ~SeExprEdExpression(); + + SeExprVarRef* resolveVar(const std::string& name) const; + SeExprFunc* resolveFunc(const std::string& name) const; + void setExpr(const std::string& str); + void clearVars(); +}; + + +#endif diff --git a/src/SeExprEditor/SeExprEdFileDialog.cpp b/src/SeExprEditor/SeExprEdFileDialog.cpp new file mode 100644 index 00000000..6edae272 --- /dev/null +++ b/src/SeExprEditor/SeExprEdFileDialog.cpp @@ -0,0 +1,486 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ + +// NOTE: This is based on Dan's paint3d FileDialog + +#include "SeExprEdFileDialog.h" + + +#include +#include +#include +#include +#include +#include + +using std::max; +using std::min; + +static const char* folder_fav[]={ + "17 16 4 1", + "# c #000000", + ". c None", + "a c #ffff98", + "b c #cc0000", + ".................", + ".................", + "...#####.........", + "..#aaaaa#........", + ".###############.", + ".#aaaaaaaaaaaaa#.", + ".#aaaa##a##aaaa#.", + ".#aaa#bb#bb#aaa#.", + ".#aaa#bbbbb#aaa#.", + ".#aaa#bbbbb#aaa#.", + ".#aaaa#bbb#aaaa#.", + ".#aaaaa#b#aaaaa#.", + ".#aaaaaa#aaaaaa#.", + ".#aaaaaaaaaaaaa#.", + ".###############.", + "................."}; + + +void SeExprEdPreviewWidget::makePreview(const QString& path) +{ + QFileInfo fi( path ); + + if ( fi.isDir() ) + { + QString s = fi.absoluteFilePath()+"/preview.tif"; + if (!QFile::exists(s)) s = fi.absoluteFilePath()+"/preview.png"; + if (!QFile::exists(s)) _pm->setPixmap( QPixmap()); //nothing to preview + + QPixmap pix( s ); + if ( !pix.isNull() ) _pm->setPixmap( pix ); + else _pm->setPixmap( QPixmap() ); + } + else if (fi.exists()) + { + QImage img(fi.absoluteFilePath()); + if(!img.isNull()) + _pm->setPixmap(QPixmap::fromImage(img.scaled(128,128,Qt::KeepAspectRatio,Qt::SmoothTransformation))); + else + _pm->setPixmap( QPixmap() ); + } + else _pm->setPixmap( QPixmap() ); + _pm->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); +} + + +SeExprEdPreviewWidget::SeExprEdPreviewWidget( QWidget *parent ) + : QWidget( parent ) +{ + _pm = new QLabel( this ); + _pm->setFrameStyle( QFrame::StyledPanel ); + _pm->setBackgroundRole( QPalette::Base ); + _pm->setAutoFillBackground(true); + QVBoxLayout *layout = new QVBoxLayout; + layout->setSpacing( 0 ); + layout->setMargin( 0 ); + layout->addWidget(_pm); + setLayout(layout); +} + +SeExprEdFileDialog::SeExprEdFileDialog(QWidget* parent) : QFileDialog(parent) +{ + //QStringList pathlist(QString(globals.startpath.c_str())); + //addLookInEntries(pathlist); + + _nameEdit = 0; + _okButton = 0; + + // disconnect broken return press handling (mishandles new directory names) + QList lineedits = findChildren(QRegExp()); + if (lineedits.size()) _nameEdit = (QLineEdit*)lineedits.at(0); + if (_nameEdit) { + _nameEdit->disconnect(SIGNAL(returnPressed())); + connect(_nameEdit, SIGNAL(returnPressed()), SLOT(editReturnPress())); + } + + // connect custom ok clicked handler + QList myWidgets = findChildren(QRegExp()); + for (int w = 0; w < myWidgets.size(); w++) + { + QPushButton* item = (QPushButton*)myWidgets.at(w); + if (item->text().contains("Open")) _okButton = item; + } + if (_okButton) connect(_okButton, SIGNAL(clicked()), SLOT(handleOk())); + + connect(this, SIGNAL(currentChanged(const QString&)), + this, SLOT(selChanged(const QString&))); + + // don't create missing directories by default + _createDir = 0; + _pw = 0; + _favDir = ""; + _combo = 0; + _combolabel = 0; + _cb = 0; + _temppath = ""; + + setMinimumWidth(680); + resize(840,440); +} + +void SeExprEdFileDialog::handleOk() +{ + if (fileMode() != QFileDialog::DirectoryOnly) return; + QString entry = _nameEdit->text(); + if (entry == "") return; + + // create directory if needed + if (_createDir) { + QDir d(directory()); + if (!d.exists(entry)) { + if (d.mkdir(entry)) { + _temppath = directory().absolutePath(); + setDirectory(_temppath+"/"+entry); + _nameEdit->setText(""); + if (_okButton) + _okButton->animateClick(); // retry click to accept entry + + QTimer::singleShot( 200, this, SLOT(resetDir()) ); + } + } + } +} + +void SeExprEdFileDialog::editReturnPress() +{ + if (!_nameEdit) return; + + QString str = _nameEdit->text(); + if (str.contains('/')) + { + QDir d; + if (d.cd(str)) + { + setDirectory(str); + _nameEdit->setText(""); + } + else + { + int slashcount = str.count('/'); + + QString foundDir = ""; + for (int i=0; isetText(remainder); + } + + if (d.cd(str)) setDirectory(str); + + } + } + else if (fileMode()==QFileDialog::DirectoryOnly) handleOk(); + else accept(); +} + +void SeExprEdFileDialog::addFavoritesButton(QString dirname, QString linkname, + QString linkdir) +{ + QGridLayout *layout = findChild("gridLayout"); + if (!layout) return; + + QDir d; + + std::string favlocation = getenv("HOME"); + favlocation += "/paint3d/favorites/"; + + QString dirpath = QString::fromStdString(favlocation); + if (!d.cd(dirpath)) d.mkpath(dirpath); + dirpath += dirname; + if (!d.cd(dirpath)) d.mkpath(dirpath); + + if (!(linkdir.isEmpty() || linkname.isEmpty())) + { + if (!QFile::exists(dirpath+linkname)) + QFile::link(linkdir,dirpath+linkname); + } + + _favDir = dirpath; + + static QPixmap folderFav( folder_fav ); + QToolButton* fav = new QToolButton(this); + fav->setFixedSize(18,18); + fav->setIcon(folderFav); + fav->setToolTip("Favorites"); + + layout->addWidget(fav,0,3); + + connect(fav, SIGNAL(clicked()), SLOT(gotoFavorites())); +} + +void SeExprEdFileDialog::gotoFavorites() +{ + if (_favDir!="") setDirectory( _favDir ); +} + +void SeExprEdFileDialog::addLookInEntries(QStringList paths) +{ + if ( paths.isEmpty ()) return; + + QStringList h = history(); + for (QStringList::Iterator it=paths.begin(); it!=paths.end(); ++it) + { + if (!h.contains(*it)) h.push_back(*it); + } + setHistory(h); +} + +void SeExprEdFileDialog::saveLookInEntries() +{ + _lookInList = history(); +} + +void SeExprEdFileDialog::restoreLookInEntries() +{ + setHistory(_lookInList); +} + +static QStringList makeFiltersList( const QString &filter ) +{ + if ( filter.isEmpty() ) + return QStringList(); + + int i = filter.indexOf( ";;", 0 ); + QString sep( ";;" ); + if ( i == -1 ) { + if ( filter.indexOf( "\n", 0 ) != -1 ) { + sep = "\n"; + i = filter.indexOf( sep, 0 ); + } + } + + return filter.split( sep ); +} + +QString SeExprEdFileDialog::getOpenFileName( const QString& caption, + const QString& startWith, const QString& filter ) +{ + if ( !filter.isEmpty() ) + { + QStringList filters = makeFiltersList( filter ); + setNameFilters( filters ); + } + + if ( !startWith.isEmpty() ) setDirectory( startWith ); + if ( !caption.isNull() ) setWindowTitle( caption ); + setFileMode( QFileDialog::ExistingFile ); + setAcceptMode( QFileDialog::AcceptOpen ); + selectFile(""); + + QString result; + if ( exec()==QDialog::Accepted ) + { + result = selectedFiles().first(); + _workingDirectory = directory().absolutePath(); + } + resetPreview(); + + return result; +} + +QStringList SeExprEdFileDialog::getOpenFileNames( const QString& caption, + const QString& startWith, const QString& filter ) +{ + if ( !filter.isEmpty() ) + { + QStringList filters = makeFiltersList( filter ); + setNameFilters( filters ); + } + + if ( !startWith.isEmpty() ) setDirectory( startWith ); + if ( !caption.isNull() ) setWindowTitle( caption ); + setFileMode( QFileDialog::ExistingFiles ); + setAcceptMode( QFileDialog::AcceptOpen ); + selectFile(""); + + QString result; + QStringList lst; + if ( exec()==QDialog::Accepted ) + { + lst = selectedFiles(); + _workingDirectory = directory().absolutePath(); + } + resetPreview(); + + return lst; +} + +QString SeExprEdFileDialog::getExistingDirectory( const QString& caption, + const QString& startWith, const QString& filter ) +{ + if ( !filter.isEmpty() ) + { + QStringList filters = makeFiltersList( filter ); + setNameFilters( filters ); + } + + if ( !startWith.isEmpty() ) setDirectory( startWith ); + if ( !caption.isNull() ) setWindowTitle( caption ); + setFileMode( QFileDialog::DirectoryOnly ); + selectFile(""); + + QString result; + if ( exec()==QDialog::Accepted ) + { + result = selectedFiles().first(); + _workingDirectory = directory().absolutePath(); + } + resetPreview(); + + return result; +} + +QString SeExprEdFileDialog::getExistingOrNewDirectory( const QString& caption, + const QString& startWith, const QString& filter ) +{ + _createDir = 1; + QString result = getExistingDirectory(caption, startWith, filter); + _createDir = 0; + resetPreview(); + return result; +} + +QString SeExprEdFileDialog::getSaveFileName( const QString& caption, + const QString& startWith, const QString& filter ) +{ + if ( !filter.isEmpty() ) + { + QStringList filters = makeFiltersList( filter ); + setNameFilters( filters ); + } + + if ( !startWith.isEmpty() ) setDirectory( startWith ); + if ( !caption.isNull() ) setWindowTitle( caption ); + setFileMode( QFileDialog::AnyFile ); + setAcceptMode( QFileDialog::AcceptSave ); + selectFile(""); + + QString result; + if ( exec()==QDialog::Accepted ) + { + result = selectedFiles().first(); + _workingDirectory = directory().absolutePath(); + } + resetPreview(); + + return result; +} + + +void SeExprEdFileDialog::setPreview() +{ + QGridLayout *layout = findChild("gridLayout"); + if (!layout) return; + + _pw = new SeExprEdPreviewWidget( this ); + _pw->setFixedWidth(160); + _pw->setMinimumHeight(160); + layout->addWidget(_pw,1,3); +} + +void SeExprEdFileDialog::resetPreview() +{ + if (_pw) _pw->reset(); +} + +void SeExprEdFileDialog::addCheckBox(QString s) +{ + QGridLayout *layout = findChild("gridLayout"); + if (!layout) return; + + _cb = new QCheckBox( s, this ); + _cb->setChecked(false); + + layout->addWidget(_cb, 4, _combo ? 2 : 0); +} + +bool SeExprEdFileDialog::checkBoxStatus() +{ + if (!_cb) return false; + return _cb->isChecked(); +} + +void SeExprEdFileDialog::showCheckBox() +{ + if (_cb) _cb->show(); +} + +void SeExprEdFileDialog::hideCheckBox() +{ + if (_cb) _cb->hide(); +} + +void SeExprEdFileDialog::addComboBox(QString s, QStringList sl) +{ + QGridLayout *layout = findChild("gridLayout"); + if (!layout) return; + + _combolabel = new QLabel( s, this ); + _combolabel->setFixedWidth(58); + _combo = new QComboBox( this ); + _combo->setEditable(true); + _combo->setFixedWidth(160); + for ( QStringList::Iterator it = sl.begin(); it != sl.end(); ++it ) + _combo->addItem(*it); + + int rownum = layout->rowCount(); + layout->addWidget(_combo,rownum,1); + layout->addWidget(_combolabel,rownum,0); +} + +void SeExprEdFileDialog::showComboBox() +{ + if (_combo) _combo->show(); + if (_combolabel) _combolabel->show(); +} + +void SeExprEdFileDialog::hideComboBox() +{ + if (_combo) _combo->hide(); + if (_combolabel) _combolabel->hide(); +} + +void SeExprEdFileDialog::selChanged(const QString& path) +{ + if (_pw) _pw->makePreview(path); +} + +void SeExprEdFileDialog::setButtonName(const QString& str) +{ + if (_okButton) _okButton->setText( str ); +} + +void SeExprEdFileDialog::addSidebarShortcut(const QString& s) +{ + QList urls = sidebarUrls(); + QUrl url = QUrl::fromLocalFile(s); + if (url.isValid() && QFile::exists(s)) + { + urls.push_back(url); + setSidebarUrls(urls); + } +} diff --git a/src/SeExprEditor/SeExprEdFileDialog.h b/src/SeExprEditor/SeExprEdFileDialog.h new file mode 100644 index 00000000..ecbaced8 --- /dev/null +++ b/src/SeExprEditor/SeExprEdFileDialog.h @@ -0,0 +1,103 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ + +// NOTE: This is based on Dan's paint3d FileDialog + +#ifndef QDSEFILEDIALOG_H +#define QDSEFILEDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +class SeExprEdPreviewWidget : public QWidget +{ +public: + SeExprEdPreviewWidget( QWidget *parent ); + void makePreview(const QString& path); + void reset() { _pm->setPixmap(QPixmap()); } + +private: + QLabel* _pm; +}; + + +class SeExprEdFileDialog : public QFileDialog +{ + Q_OBJECT + public: + SeExprEdFileDialog( QWidget* parent = 0 ); + void addLookInEntries(QStringList paths); + void saveLookInEntries(); + void restoreLookInEntries(); + QString getOpenFileName( const QString & caption = QString::null, + const QString & startWith = QString::null, + const QString & filter = QString::null ); + QString getExistingDirectory( const QString & caption = QString::null, + const QString & startWith = QString::null, + const QString & filter = QString::null ); + QString getExistingOrNewDirectory( const QString & caption = QString::null, + const QString & startWith = QString::null, + const QString & filter = QString::null ); + QStringList getOpenFileNames( const QString & caption = QString::null, + const QString & startWith = QString::null, + const QString & filter = QString::null ); + QString getSaveFileName( const QString & caption = QString::null, + const QString & startWith = QString::null, + const QString & filter = QString::null ); + void setPreview(); + void resetPreview(); + void addCheckBox(QString s); + void addFavoritesButton(QString dirname, QString linkname, QString linkdir); + bool checkBoxStatus(); + void showCheckBox(); + void hideCheckBox(); + void addComboBox(QString s, QStringList sl); + void showComboBox(); + void hideComboBox(); + QComboBox* getComboBox() { return _combo; } + void setButtonName(const QString& str); + void addSidebarShortcut(const QString& s); + + private slots: + void handleOk(); + void editReturnPress(); + void gotoFavorites(); + void selChanged(const QString& path); + void resetDir() + { if (!_temppath.isEmpty()) setDirectory(_temppath); _temppath = ""; } + + private: + QString _workingDirectory, _favDir; + QString _temppath; + QStringList _lookInList; + QLineEdit* _nameEdit; + QPushButton* _okButton; + bool _createDir; + SeExprEdPreviewWidget* _pw; + QCheckBox* _cb; + QLabel* _combolabel; + QComboBox* _combo; +}; + +#endif diff --git a/src/SeExprEditor/SeExprEdGrapher2d.cpp b/src/SeExprEditor/SeExprEdGrapher2d.cpp new file mode 100644 index 00000000..a58ea6a3 --- /dev/null +++ b/src/SeExprEditor/SeExprEdGrapher2d.cpp @@ -0,0 +1,253 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdGrapherView.cpp +* @brief A 2d image graph view for expression editing previewing +* @author jlacewel +*/ + +#include "SeExprEdGrapher2d.h" +#include +#include +#include +#include +#include + + +SeExprEdGrapherWidget::SeExprEdGrapherWidget(QWidget* parent,int width,int height) + :view(new SeExprEdGrapherView(*this,this,width,height)),expr("",false) +{ + Q_UNUSED(parent); + setFixedSize(width, height+30); + QVBoxLayout* vbox=new QVBoxLayout; + vbox->setMargin(0); + setLayout(vbox); + vbox->addWidget(view,0,Qt::AlignLeft | Qt::AlignTop); + QHBoxLayout* hbox=new QHBoxLayout; + vbox->addLayout(hbox); + hbox->setMargin(0); + + float xmin,xmax,ymin,ymax,z; + view->getWindow(xmin,xmax,ymin,ymax,z); + scale=new QLineEdit(); + QDoubleValidator *valValidator = new QDoubleValidator(0.0,10000000.0,6,scale); + scale->setValidator(valValidator); + scale->setValidator(valValidator); + scaleValueManipulated(); + + + connect(scale, SIGNAL(returnPressed()), this, SLOT(scaleValueEdited())); + connect(view, SIGNAL(scaleValueManipulated()), this, SLOT(scaleValueManipulated())); + connect(view, SIGNAL(clicked()), this, SLOT(forwardPreview())); + + hbox->addWidget(new QLabel("Width"),0); + hbox->addWidget(scale,0); +} + +void SeExprEdGrapherWidget::scaleValueEdited() +{ + float xmin,xmax,ymin,ymax,z; + view->getWindow(xmin,xmax,ymin,ymax,z); + float xdiff=xmax-xmin,ydiff=ymax-ymin; + float xcenter=.5*(xmax+xmin),ycenter=.5*(ymin+ymax); + float newScale=atof(scale->text().toStdString().c_str()); + + float aspect=ydiff/xdiff; + + xmin=xcenter-newScale; + xmax=xcenter+newScale; + ymin=ycenter-aspect*newScale; + ymax=ycenter+aspect*newScale; + view->setWindow(xmin,xmax,ymin,ymax,z); +} + +void SeExprEdGrapherWidget::scaleValueManipulated() +{ + float xmin,xmax,ymin,ymax,z; + view->getWindow(xmin,xmax,ymin,ymax,z); + scale->setText(QString("%1").arg(.5*(xmax-xmin))); +} + +void SeExprEdGrapherWidget::update() +{ + expr.setWantVec(true); + + view->update(); +} + +void SeExprEdGrapherWidget::forwardPreview() +{ + emit preview(); +} + + +SeExprEdGrapherView::SeExprEdGrapherView(SeExprEdGrapherWidget& widget,QWidget* parent, int width, int height) + : QGLWidget(parent), widget(widget), _image(NULL), _width(width), _height(height), + scaling(false),translating(false) +{ + this->setFixedSize(width, height); + + _image = new float[3*_width*_height]; + setWindow(-1,1,-1,1,0); + clear(); + + setCursor(Qt::OpenHandCursor); + +} + +SeExprEdGrapherView::~SeExprEdGrapherView() +{ + delete [] _image; +} + +void SeExprEdGrapherView::setWindow(float xmin,float xmax,float ymin,float ymax,float z) +{ + this->z=z; + this->xmin=xmin; + this->xmax=xmax; + this->ymin=ymin; + this->ymax=ymax; + + dx=(xmax-xmin)/_width; + dy=(ymax-ymin)/_height; +} + +void SeExprEdGrapherView::getWindow(float& xmin,float& xmax,float& ymin,float& ymax,float& z) +{ + z=this->z; + xmin=this->xmin; + xmax=this->xmax; + ymin=this->ymin; + ymax=this->ymax; +} + +void SeExprEdGrapherView::clear() +{ + for (int row = 0; row < _height; ++row) { + for (int col = 0; col < _width; ++col) { + int index = 3*row*_width + 3*col; + _image[index] = 1.0f; + _image[index+1] = 0.0f; + _image[index+2] = 0.0f; + } + } +} + +void SeExprEdGrapherView::mousePressEvent(QMouseEvent* event) +{ + if(event->button()==Qt::MidButton){ + setCursor(Qt::ClosedHandCursor); + translating=true; + } + if(event->button()==Qt::RightButton){ + setCursor(Qt::SizeAllCursor); + scaling=true; + } + event_oldx=event->x(); + event_oldy=event->y(); + +} +void SeExprEdGrapherView::mouseReleaseEvent(QMouseEvent* event) +{ + if(event->button()==Qt::LeftButton) + emit clicked(); + scaling=translating=false; + setCursor(Qt::OpenHandCursor); +} +void SeExprEdGrapherView::mouseMoveEvent(QMouseEvent* event) +{ + int x=event->x(),y=event->y(); + float offsetx=dx*(x-event_oldx); + float offsety=-dy*(y-event_oldy); + + if(translating){ + xmin-=offsetx; + xmax-=offsetx; + ymin-=offsety; + ymax-=offsety; + update(); + repaint(); + }else if(scaling){ + float offset=(fabs(offsetx)>fabs(offsety))?offsetx:offsety; + + float width=.5*(xmax-xmin),height=.5*(ymax-ymin); + float xcenter=.5*(xmin+xmax),ycenter=.5*(ymin+ymax); + // Use float args for pow() to fix Windows compile error + float scale_factor=pow(10.f,-offset/(xmax-xmin)); + width*=scale_factor; + height*=scale_factor; + setWindow(xcenter-width,xcenter+width,ycenter-height,ycenter+height,z); + emit scaleValueManipulated(); + update(); + repaint(); + } + event_oldx=x; + event_oldy=y; +} + + +void SeExprEdGrapherView::update() +{ + + if (!widget.expr.isValid()) { + clear(); + updateGL(); + return; + } + + + float dv = 1.0f / _height; + float du = 1.0f / _width; + + float y=.5*dy+ymin; + float v=.5*dv; + int index=0; + for(int row=0;row<_height;row++,y+=dy,v+=dv){ + float x=.5*dx+xmin; + float u=.5*du; + widget.expr.v.value=v; + for(int col=0;col<_width;col++,x+=dy,u+=du){ + widget.expr.u.value=u; + widget.expr.P.value=SeVec3d(x,y,z); + double* value=widget.expr.evaluate(); + _image[index] = value[0]; + _image[index+1] = value[1]; + _image[index+2] = value[2]; + index+=3; + } + } + + updateGL(); +} + +void SeExprEdGrapherView::paintGL() +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0f, (GLfloat)_width, 0.0, (GLfloat)_height, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDisable(GL_DEPTH_TEST); + glDepthFunc(0); + glClearColor(1,0,0,1); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glRasterPos2i(0,0); + glDrawPixels(_width, _height, GL_RGB, GL_FLOAT, _image); + +} + diff --git a/src/SeExprEditor/SeExprEdGrapher2d.h b/src/SeExprEditor/SeExprEdGrapher2d.h new file mode 100644 index 00000000..6a2fe78f --- /dev/null +++ b/src/SeExprEditor/SeExprEdGrapher2d.h @@ -0,0 +1,92 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdGrapher2d.h +* @brief A 2d image graph view for expression editing previewing +* @author jlacewel +*/ +#ifndef SeExprEdGrapher2d_h +#define SeExprEdGrapher2d_h + +#include +#include +#include +#include + +#include "SeExprEdExpression.h" + +class SeExprEdGrapherWidget; +class QLineEdit; + +class SeExprEdGrapherView : public QGLWidget +{ + Q_OBJECT; + SeExprEdGrapherWidget& widget; +public: + SeExprEdGrapherView(SeExprEdGrapherWidget& widget,QWidget* parent, int width, int height); + virtual ~SeExprEdGrapherView(); + + void update(); + void setWindow(float xmin,float xmax,float ymin,float ymax,float z); + void getWindow(float &xmin,float& xmax,float& ymin,float &ymax,float &z); + + protected: + void clear(); + void paintGL(); + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event); + int event_oldx,event_oldy; + + signals: + void scaleValueManipulated(); + void clicked(); + + private: + float * _image; + int _width; + int _height; + + float xmin,xmax,ymin,ymax,z; + float dx,dy; + + + bool scaling,translating; + +}; + +class SeExprEdGrapherWidget : public QWidget +{ + Q_OBJECT + QLineEdit* scale; + + public: + SeExprEdGrapherView* view; + SeExprEdExpression expr; + + SeExprEdGrapherWidget(QWidget* parent, int width, int height); + + void update(); +signals: + void preview(); +private slots: + void scaleValueEdited(); + void scaleValueManipulated(); + void forwardPreview(); + +}; + +#endif diff --git a/src/SeExprEditor/SeExprEdHelp.h b/src/SeExprEditor/SeExprEdHelp.h new file mode 100644 index 00000000..d199f928 --- /dev/null +++ b/src/SeExprEditor/SeExprEdHelp.h @@ -0,0 +1,52 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +//#include "SeExprEdHelp.h" +#if 0 +header + + QTextBrowser* helpBrowser; + +constructor + + QWidget* browserspace = new QWidget(tab); + helpBrowser = new QTextBrowser(browserspace); + tab->addTab(browserspace, "Help"); + char * path = getenv("RP_SeExpr"); + if (path) + helpBrowser->setSource(QString("%1/share/doc/SeExpr/SeExpressions.html").arg(path)); + + QPushButton* backPb = new QPushButton("Back"); + backPb->setEnabled(false); + QPushButton* forwardPb = new QPushButton("Forward"); + forwardPb->setEnabled(false); + + QVBoxLayout * helpLayout = new QVBoxLayout(browserspace); + QHBoxLayout * helpPbLayout = new QHBoxLayout; + helpLayout->addLayout(helpPbLayout); + helpPbLayout->addWidget(backPb); + helpPbLayout->addWidget(forwardPb); + helpPbLayout->addItem(new QSpacerItem(0,0, QSizePolicy::MinimumExpanding, + QSizePolicy::Minimum)); + helpLayout->addWidget(helpBrowser, /*stretch*/ true); + helpBrowser->setMinimumHeight(120); + + // wire up help browser forward/back buttons + connect(backPb, SIGNAL(clicked()), helpBrowser, SLOT(backward())); + connect(forwardPb, SIGNAL(clicked()), helpBrowser, SLOT(forward())); + connect(helpBrowser, SIGNAL(backwardAvailable(bool)), backPb, SLOT(setEnabled(bool))); + connect(helpBrowser, SIGNAL(forwardAvailable(bool)), forwardPb, SLOT(setEnabled(bool))); +#endif diff --git a/src/SeExprEditor/SeExprEdHighlighter.h b/src/SeExprEditor/SeExprEdHighlighter.h new file mode 100644 index 00000000..17199163 --- /dev/null +++ b/src/SeExprEditor/SeExprEdHighlighter.h @@ -0,0 +1,107 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdHighlighter.h +* @brief A Qt syntax highlighter for the SeExpr language +* @author aselle +*/ +#ifndef _SeExprEdHighlighter_h_ +#define _SeExprEdHighlighter_h_ +#include +#include +#include + +class SeExprEdHighlighter : public QSyntaxHighlighter +{ + struct HighlightingRule{ + QRegExp pattern; + QTextCharFormat format; + }; + QVector highlightingRules; + QTextCharFormat singleLineCommentFormat; + QTextCharFormat variableFormat; + QTextCharFormat numberFormat; + QTextCharFormat operatorFormat; + + int lightness; + +public: + SeExprEdHighlighter(QTextDocument* parent) + :QSyntaxHighlighter(parent),lightness(130) + { + init(); + } + + SeExprEdHighlighter(QTextEdit* edit) + :QSyntaxHighlighter(edit),lightness(130) + { + init(); + } + + void fixStyle(const QPalette& palette) + { + lightness=palette.color(QPalette::Base).value()<127 ? 250: 130; + init(); + } + + void init() + { + HighlightingRule rule; + highlightingRules.clear(); + + // Operator highlighting, disabled for now + //operatorFormat.setForeground(QColor::fromHsv(50,128,lightness)); + //QStringList operatorPatterns; + //operatorPatterns<<"(?:->)|(?:[()\\+-/\\*%\\^:\\?\\[\\]])"; + //foreach (QString pattern,operatorPatterns){ + // rule.pattern=QRegExp(pattern); + // rule.format=operatorFormat; + // highlightingRules.append(rule); + //} + + numberFormat.setForeground(QColor::fromHsv(180,204,lightness)); + rule.pattern=QRegExp("\\b[0-9]*\\.[0-9]*)?|[0-9]+\\b"); // \\b?[^\\$][A-Za-z][A-Za-z0-9]*\\b"); + rule.format=numberFormat; + //highlightingRules.append(rule); + + variableFormat.setForeground(QColor::fromHsv(200,153,lightness)); + //variableFormat.setFontWeight(QFont::Bold); + rule.pattern=QRegExp("\\$[A-Za-z][A-Za-z0-9]*\\b"); + rule.format=variableFormat; + highlightingRules.append(rule); + + singleLineCommentFormat.setForeground(QColor::fromHsv(210,128,lightness)); + rule.pattern=QRegExp("#[^\n]*"); + rule.format=singleLineCommentFormat; + highlightingRules.append(rule); + + } + + void highlightBlock(const QString& text) + { + foreach (HighlightingRule rule,highlightingRules){ + QRegExp expression(rule.pattern); + int index=text.indexOf(expression); + while(index>=0){ + int length=expression.matchedLength(); + setFormat(index,length,rule.format); + index=text.indexOf(expression,index+length); + } + } + setCurrentBlockState(0); + } +}; +#endif diff --git a/src/SeExprEditor/SeExprEdPopupDocumentation.cpp b/src/SeExprEditor/SeExprEdPopupDocumentation.cpp new file mode 100644 index 00000000..510bd64e --- /dev/null +++ b/src/SeExprEditor/SeExprEdPopupDocumentation.cpp @@ -0,0 +1,41 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include "SeExprEdPopupDocumentation.h" +#include +#include + +SeExprEdPopupDocumentation::SeExprEdPopupDocumentation(QWidget* parent,const QPoint& placecr,const QString& msg) +{ + Q_UNUSED(parent); + label=new QLabel(msg); + QHBoxLayout* layout=new QHBoxLayout; + setLayout(layout); + layout->addWidget(label); + + setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint |Qt::X11BypassWindowManagerHint ); + setFocusPolicy(Qt::NoFocus); + move(placecr); + raise(); + show(); +} + +void SeExprEdPopupDocumentation:: +mousePressEvent ( QMouseEvent * event ) +{ + Q_UNUSED(event); + hide(); +} diff --git a/src/SeExprEditor/SeExprEdPopupDocumentation.h b/src/SeExprEditor/SeExprEdPopupDocumentation.h new file mode 100644 index 00000000..c349a226 --- /dev/null +++ b/src/SeExprEditor/SeExprEdPopupDocumentation.h @@ -0,0 +1,35 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef _SeExprEdPopupDocumentation_h_ +#define _SeExprEdPopupDocumentation_h_ + +#include + +class QLabel; +class SeExprEdPopupDocumentation:public QWidget +{ + Q_OBJECT; + +public: + QLabel* label; + SeExprEdPopupDocumentation(QWidget* parent,const QPoint& cr,const QString& msg); + +protected: + void mousePressEvent ( QMouseEvent * event ); +}; + +#endif diff --git a/src/SeExprEditor/SeExprEdShortEdit.cpp b/src/SeExprEditor/SeExprEdShortEdit.cpp new file mode 100644 index 00000000..9ae7cdac --- /dev/null +++ b/src/SeExprEditor/SeExprEdShortEdit.cpp @@ -0,0 +1,538 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdShortEdit.cpp +* @brief This provides an exression editor for SeExpr syntax with auto ui features +* @author aselle +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "SeExprEdShortEdit.h" +#include "SeExprEdDialog.h" +#include "SeExprEdBrowser.h" +#include "SeExprEdHighlighter.h" +#include "SeExprEdCompletionModel.h" +#include "SeExprEdControlCollection.h" +#include "SeExprEdPopupDocumentation.h" +#include "SeExprEdExpression.h" + + +/* XPM */ +static const char *sum_xpm[]={ +"16 16 6 1", +"# c None", +". c None", +"b c #808080", +"d c #010000", +"c c #aaaaaa", +"a c #303030", +"................", +".#aaaaaaaaaa##..", +".abbbbbbcbbba...", +".#abbaaaaabba...", +"..#aabba..aba...", +"....#abba..a#...", +".....#abba......", +".....#abba......", +"...##abba...#...", +"...#abba...aa...", +"..#abba...aca...", +".#abbaaaaabba...", +".abbbbbbbbbba...", +".aaaaaaaaaaa#...", +"................", +"................"}; + +/* XPM */ +static const char *stop_xpm[] = { +"16 16 4 1", +" c None", +". c #FF0000", +"+ c #FF8080", +"@ c #FFFFFF", +" ", +" ", +" ...... ", +" ...+++.. ", +" ....@@@... ", +" .....@@@.... ", +" .....@@@.... ", +" .....@@@.... ", +" .....@@@.... ", +" ............ ", +" ....@@@.... ", +" ...@@@... ", +" ....... ", +" ..... ", +" ", +" "}; + + + +SeExprEdShortEdit::SeExprEdShortEdit(QWidget* parent, bool expanded) + :QWidget(parent), _context(""), _searchPath("") +{ + controlRebuildTimer=new QTimer(); + + vboxlayout=new QVBoxLayout(); + vboxlayout->setMargin(0); + hboxlayout=new QHBoxLayout(); + hboxlayout->setMargin(0); + //edit=new SeExprEdShortEdit(); + //edit=new QLineEdit(); + edit=new SeExprEdShortTextEdit(parent); + + error=new QLabel(); + error->setPixmap(QPixmap(stop_xpm)); + error->setHidden(true); + + expandButton=new QToolButton; + expandButton->setMinimumSize(20,20); + expandButton->setMaximumSize(20,20); + expandButton->setFocusPolicy(Qt::NoFocus); + if (expanded) expandButton->setArrowType(Qt::DownArrow); + else expandButton->setArrowType(Qt::RightArrow); + connect(expandButton,SIGNAL(clicked()),SLOT(expandPressed())); + + QToolButton* button=new QToolButton; + editDetail=button; + button->setIcon(QIcon(QPixmap(sum_xpm))); + hboxlayout->addWidget(expandButton); + hboxlayout->addWidget(edit); + hboxlayout->addWidget(error); + hboxlayout->addWidget(editDetail); + + editDetail->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); + editDetail->setMinimumSize(20,20); + editDetail->setMaximumSize(20,20); + connect(editDetail,SIGNAL(clicked()),SLOT(detailPressed())); + //connect(edit,SIGNAL(textChanged()),SLOT(handleTextEdited())); + connect(edit,SIGNAL(editingFinished()),SLOT(textFinished())); + + vboxlayout->addLayout(hboxlayout); + + controls=0; + if (expanded) expandPressed(); + + setLayout(vboxlayout); + connect(controlRebuildTimer, SIGNAL(timeout()), SLOT(rebuildControls())); +} + +SeExprEdShortEdit::~SeExprEdShortEdit() +{ + delete controlRebuildTimer; +} + +void SeExprEdShortEdit::setSearchPath(const QString& context, const QString& path) +{ + _context = context.toStdString(); + _searchPath = path.toStdString(); +} + +void SeExprEdShortEdit::detailPressed() +{ + showDetails(-1); +} + +int SeExprEdShortEdit::showDetails(int idx) +{ + SeExprEdDialog dialog(0); + dialog.editor->replaceExtras(*edit->completionModel); + + dialog.browser->setSearchPath(_context.c_str(), _searchPath.c_str()); + dialog.browser->expandAll(); + dialog.setExpressionString(getExpressionString()); + if (idx >= 0) { + dialog.showEditor(idx); + } + + int result = dialog.exec(); + + if (QDialog::Accepted == result) { + setExpressionString(dialog.getExpressionString()); + } + + return result; +} + +void SeExprEdShortEdit::rebuildControls() +{ + if(controls){ + bool wasShown=!edit->completer->popup()->isHidden(); + //std::vector variables; + bool newVariables=controls->rebuildControls(getExpression(),edit->completionModel->local_variables); + if (controls->numControls()==0) + { + controls->deleteLater(); + controls=0; + expandButton->setArrowType(Qt::RightArrow); + } + else vboxlayout->addWidget(controls); + if(newVariables) edit->completer->setModel(edit->completionModel); + if(wasShown) edit->completer->popup()->show(); + } +} + +void SeExprEdShortEdit::expandPressed() +{ + if(controls){ + //vboxlayout->removeWidget(controls); + controls->deleteLater(); + controls=0; + expandButton->setArrowType(Qt::RightArrow); + }else{ + controls=new SeExprEdControlCollection(0,false); + //vboxlayout->addWidget(controls); + connect(controls,SIGNAL(controlChanged(int)),SLOT(controlChanged(int))); + controlRebuildTimer->setSingleShot(true); + controlRebuildTimer->start(0); + expandButton->setArrowType(Qt::DownArrow); + } +} + +void SeExprEdShortEdit::handleTextEdited() +{} + +void SeExprEdShortEdit::textFinished() +{ + controlRebuildTimer->setSingleShot(true); + controlRebuildTimer->start(0); + checkErrors(); + emit exprChanged(); +} + +void SeExprEdShortEdit::setExpressionString(const std::string& expression) +{ + edit->setText(QString(expression.c_str()).replace("\n","\\n")); + //rebuildControls(); + controlRebuildTimer->setSingleShot(true); + controlRebuildTimer->start(0); + checkErrors(); + emit exprChanged(); +} + +QString SeExprEdShortEdit::getExpression() const +{ + return edit->toPlainText().replace("\\n","\n"); +} + +std::string SeExprEdShortEdit::getExpressionString()const +{ + return getExpression().toStdString(); +} + +void SeExprEdShortEdit::controlChanged(int id) +{ + if(controls){ + QString newText=getExpression(); + controls->updateText(id,newText); + edit->setText(newText.replace("\n","\\n")); + checkErrors(); + emit exprChanged(); + } +} + +void SeExprEdShortEdit:: +clearExtraCompleters() +{ + edit->completionModel->clearFunctions(); + edit->completionModel->clearVariables(); +} + +void SeExprEdShortEdit:: +registerExtraFunction(const std::string& name,const std::string& docString) +{ + edit->completionModel->addFunction(name.c_str(),docString.c_str()); +} + +void SeExprEdShortEdit:: +registerExtraVariable(const std::string& name,const std::string& docString) +{ + edit->completionModel->addVariable(name.c_str(),docString.c_str()); +} + +void SeExprEdShortEdit:: +updateCompleter() +{ + edit->completer->setModel(edit->completionModel); +} + +void SeExprEdShortEdit:: +checkErrors() +{ + SeExprEdExpression expr(getExpressionString(),true); + bool valid=expr.isValid(); + std::string err; + if (!valid) + err = expr.parseError(); + + hideErrors(valid, err); +} + +void SeExprEdShortEdit:: +hideErrors(bool hidden, const std::string &err) +{ + error->setHidden(hidden); + if (!hidden) { + error->setToolTip(QString::fromStdString(err)); + } +} + +void SeExprEdShortEdit:: +setSimple(bool enabled) +{ + edit->setHidden(enabled); + editDetail->setHidden(enabled); + expandButton->setHidden(enabled); +} + +void SeExprEdShortEdit::setDetailsMenu(QMenu *menu) +{ + editDetail->setMenu(menu); +} + +void SeExprEdShortEdit::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy) +{ + edit->setVerticalScrollBarPolicy(policy); +} + + +SeExprEdShortTextEdit::SeExprEdShortTextEdit(QWidget* parent) +:QTextEdit(parent),editing(false),_tip(0) +{ + lastStyleForHighlighter=0; + setMaximumHeight(25); + highlighter=new SeExprEdHighlighter(document()); + highlighter->fixStyle(palette()); + highlighter->rehighlight(); + repaint(); + + // setup auto completion + completer=new QCompleter(); + completionModel=new SeExprEdCompletionModel(this); + completer->setModel(completionModel); + QTreeView* treePopup=new QTreeView; + completer->setPopup(treePopup); + treePopup->setRootIsDecorated(false); + treePopup->setMinimumWidth(300); + treePopup->setMinimumHeight(50); + treePopup->setItemsExpandable(true); + + completer->setWidget(this); + completer->setCompletionMode(QCompleter::PopupCompletion); + completer->setCaseSensitivity(Qt::CaseInsensitive); + QObject::connect(completer,SIGNAL(activated(const QString&)),this, + SLOT(insertCompletion(const QString&))); + +} + +void SeExprEdShortTextEdit::focusInEvent(QFocusEvent* e) +{ + //setTextCursor(QTextCursor(document())); + if(completer) completer->setWidget(this); + QTextEdit::focusInEvent(e); +} + +void SeExprEdShortTextEdit::focusOutEvent(QFocusEvent* e) +{ + //setTextCursor(QTextCursor()); + finishEdit(); + QTextCursor newCursor=textCursor(); + newCursor.clearSelection(); + setTextCursor(newCursor); + setColor(false); + hideTip(); + QTextEdit::focusOutEvent(e); +} + +void SeExprEdShortTextEdit::mousePressEvent(QMouseEvent* event) +{ + hideTip(); + QTextEdit::mousePressEvent(event); +} + +void SeExprEdShortTextEdit::mouseDoubleClickEvent(QMouseEvent* event) +{ + hideTip(); + QTextEdit::mouseDoubleClickEvent(event); +} + +void SeExprEdShortTextEdit::paintEvent(QPaintEvent* e){ + if(lastStyleForHighlighter!=style()){ + lastStyleForHighlighter=style(); + highlighter->fixStyle(palette()); + highlighter->rehighlight(); + } + QTextEdit::paintEvent(e); +} + + +void SeExprEdShortTextEdit::keyPressEvent( QKeyEvent* e ) +{ + + + // If the completer is active pass keys it needs down + if(completer && completer->popup()->isVisible()){ + switch(e->key()){ + case Qt::Key_Enter:case Qt::Key_Return:case Qt::Key_Escape: + case Qt::Key_Tab:case Qt::Key_Backtab: + e->ignore();return; + default: + break; + } + } + + // Accept expression + if (e->key()==Qt::Key_Return || e->key()==Qt::Key_Enter){ + selectAll(); + finishEdit(); + return; + }else if (e->key()==Qt::Key_Escape){ + setText(savedText); + selectAll(); + finishEdit(); + return; + }else if(e->key()==Qt::Key_Tab){ + QWidget::keyPressEvent(e); + return; + }else if(!editing){ + editing=true; + setColor(true); + savedText=toPlainText(); + } + + + + // use the values here as long as we are not using the shortcut to bring up the editor + bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E + if (!isShortcut) // dont process the shortcut when we have a completer + QTextEdit::keyPressEvent(e); + + + const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); + if (!completer || (ctrlOrShift && e->text().isEmpty())) + return; + + bool hasModifier=(e->modifiers()!=Qt::NoModifier) && !ctrlOrShift; + + // grab the line we're on + QTextCursor tc=textCursor(); + tc.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); + QString line=tc.selectedText(); + + // matches the last prefix of a completable variable or function and extract as completionPrefix + static QRegExp completion("^(?:.*[^A-Za-z0-9_$])?((?:\\$[A-Za-z0-9_]*)|[A-Za-z]+[A-Za-z0-9_]*)$"); + int index=completion.indexIn(line); + QString completionPrefix; + if(index != -1 && !line.contains('#')){ + completionPrefix=completion.cap(1); + //std::cout<<"we have completer prefix '"<text().isEmpty() || completionPrefix.length()<1 || index==-1)){ + completer->popup()->hide(); + }else{ + + // copy the completion prefix in if we don't already have it in the completer + if(completionPrefix!=completer->completionPrefix()){ + completer->setCompletionPrefix(completionPrefix); + completer->popup()->setCurrentIndex(completer->completionModel()->index(0,0)); + } + + // display the completer + QRect cr=cursorRect(); + cr.setWidth(2*(completer->popup()->sizeHintForColumn(0)+completer->popup()->sizeHintForColumn(1) + + completer->popup()->verticalScrollBar()->sizeHint().width())); + completer->complete(cr); + hideTip(); + return; + } + + // documentation completion + static QRegExp inFunction("^(?:.*[^A-Za-z0-9_$])?([A-Za-z0-9_]+)\\([^()]*$"); + int index2=inFunction.indexIn(line); + if(index2!=-1){ + QString functionName=inFunction.cap(1); + QStringList tips=completionModel->getDocString(functionName).split("\n"); + QString tip=""+tips[0]+""; + for(int i=1;iisHidden() && _tip->label->text() == string) return; + + QRect cr=cursorRect(); + cr.setX(0); + cr.setWidth(cr.width()*3); + if(_tip){delete _tip;_tip=0;} + _tip=new SeExprEdPopupDocumentation(this,mapToGlobal(cr.bottomLeft()),string); +} + +void SeExprEdShortTextEdit::hideTip() +{ + if(_tip) _tip->hide(); +} + +void SeExprEdShortTextEdit::insertCompletion(const QString &completion) +{ + if (completer->widget() != this) return; + QTextCursor tc = textCursor(); + int extra = completion.length() - completer->completionPrefix().length(); + tc.movePosition(QTextCursor::Left); + tc.movePosition(QTextCursor::EndOfWord); + tc.insertText(completion.right(extra)); + if(completion[0]!='$') tc.insertText("("); + setTextCursor(tc); + +} + +void SeExprEdShortTextEdit::finishEdit() +{ + editing=false; + setColor(false); + emit editingFinished(); +} + + + +void SeExprEdShortTextEdit:: +setColor(bool editing) +{ + Q_UNUSED(editing); + // todo: decorate when editing +} diff --git a/src/SeExprEditor/SeExprEdShortEdit.h b/src/SeExprEditor/SeExprEdShortEdit.h new file mode 100644 index 00000000..c75bbdc0 --- /dev/null +++ b/src/SeExprEditor/SeExprEdShortEdit.h @@ -0,0 +1,149 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEdShortEdit.h +* @brief This provides an exression editor for SeExpr syntax with auto ui features +* @author aselle +*/ + + +#ifndef SeExprEdShortEditor_h +#define SeExprEdShortEditor_h + +#include +#include + +#include +#include +#include + +class SeExprEdControlCollection; +class QToolButton; +class QVBoxLayout; +class QHBoxLayout; +class QTextEdit; +class SeExprEdHighlighter; +class QCompleter; +class SeExprEdCompletionModel; +class SeExprEdShortTextEdit; +class QLabel; +class SeExprEdPopupDocumentation; + +class SeExprEdShortEdit : public QWidget +{ + Q_OBJECT + +protected: + QTimer* controlRebuildTimer; + QToolButton* editDetail; + SeExprEdControlCollection* controls; + QVBoxLayout* vboxlayout; + QHBoxLayout* hboxlayout; + QLabel* error; + std::string _context; + std::string _searchPath; +public: + SeExprEdShortEdit(QWidget* parent, bool expanded = true); + virtual ~SeExprEdShortEdit(); + + // Gets the string that is in the edit widget + std::string getExpressionString() const; + QString getExpression() const; + // Sets the string that is in the edit widget + void setExpressionString(const std::string& expression); + // Removes all extra completion symbols + void clearExtraCompleters(); + // Registers an extra function and associated do cstring + void registerExtraFunction(const std::string& name,const std::string& docString); + // Register an extra variable (i.e. $P, or $u, something provided by resolveVar) + void registerExtraVariable(const std::string& name,const std::string& docString); + // Updates the completion widget, must call after registering any new functions/variables + void updateCompleter(); + // Hides the expression part of the interface + void setSimple(bool enabled); + // Set a menu on the "details" button + void setDetailsMenu(QMenu *menu); + // Set a colon-delimited path variable for finding expressions + void setSearchPath(const QString& context, const QString& path); + // Set the vertical scrollbar policy -- set to Qt::ScrollBarAlwaysOff to + // disable it + void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy); + // Open the details window and open the Nth editor + // Pass -1 to not show the editor + int showDetails(int idx); + + virtual QSize sizeHint() const{return QSize(400, 50);} + virtual void hideErrors(bool hidden, const std::string &err); + + // Exposed via Python + QToolButton* expandButton; + SeExprEdShortTextEdit* edit; + +protected: + void checkErrors(); + +protected slots: + virtual void detailPressed(); + virtual void expandPressed(); + virtual void textFinished(); + virtual void handleTextEdited(); + virtual void controlChanged(int id); + virtual void rebuildControls(); + +signals: + void exprChanged(); +}; + + +class SeExprEdShortTextEdit:public QTextEdit +{ + Q_OBJECT; + + SeExprEdHighlighter* highlighter; + + bool editing; + QString savedText; + SeExprEdPopupDocumentation* _tip; + QStyle* lastStyleForHighlighter; + +public: + QCompleter* completer; + SeExprEdCompletionModel* completionModel; + + + SeExprEdShortTextEdit(QWidget* parent); +protected: + void showTip(const QString& string); + void hideTip(); + + void paintEvent(QPaintEvent* e); + virtual void keyPressEvent(QKeyEvent* e); + virtual void focusInEvent(QFocusEvent* e); + virtual void focusOutEvent(QFocusEvent* e); + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseDoubleClickEvent(QMouseEvent* event); + virtual void wheelEvent(QWheelEvent* e) { e->ignore(); } + + void setColor(bool editing); + void finishEdit(); +signals: + void editingFinished(); +private slots: + void insertCompletion(const QString& completion); + +}; + +#endif diff --git a/src/SeExprEditor/SeExprEditor.cpp b/src/SeExprEditor/SeExprEditor.cpp new file mode 100644 index 00000000..fadefd36 --- /dev/null +++ b/src/SeExprEditor/SeExprEditor.cpp @@ -0,0 +1,487 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEditor.cpp +* @brief This provides an exression editor for SeExpr syntax with auto ui features +* @author aselle +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "SeExprEditor.h" +#include "SeExprEdHighlighter.h" +#include "SeExprEdCompletionModel.h" +#include "SeExprEdControlCollection.h" +#include "SeExprEdCurve.h" +#include "SeExprEdColorCurve.h" +#include "SeExprEdControl.h" +#include "SeExprEdPopupDocumentation.h" + +SeExprEdLineEdit::SeExprEdLineEdit(int id, QWidget* parent) +: QLineEdit(parent), _id(id), _signaling(0) +{ + connect(this, SIGNAL(textChanged(const QString &)), SLOT(textChangedCB(const QString &))); +} + + +void SeExprEdLineEdit::textChangedCB(const QString& text) +{ + _signaling = 1; + emit textChanged(_id, text); + _signaling = 0; +} + +void SeExprEditor::controlChanged(int id) +{ + QString newText=exprTe->toPlainText(); + controls->updateText(id,newText); + _updatingText=1; + exprTe->selectAll(); + exprTe->insertPlainText(newText); + //exprTe->setPlainText(newText); + _updatingText=0; + + // schedule preview update + previewTimer->setSingleShot(true); + previewTimer->start(0); +} + +SeExprEditor::~SeExprEditor() +{ + delete controlRebuildTimer; + delete previewTimer; +} + +SeExprEdExpressionTextEdit::~SeExprEdExpressionTextEdit() +{} + +SeExprEditor::SeExprEditor(QWidget* parent,SeExprEdControlCollection* controls) + : QWidget(parent),_updatingText(0),errorHeight(0) +{ + // timers + controlRebuildTimer=new QTimer(); + previewTimer=new QTimer(); + + // title and minimum size + setWindowTitle("Expression Editor"); + setMinimumHeight(100); + + // expression controls, we need for signal connections + this->controls = controls; + + // make layout + QVBoxLayout* exprAndErrors=new QVBoxLayout; + exprAndErrors->setMargin(0); + setLayout(exprAndErrors); + + // create text editor widget + exprTe = new SeExprEdExpressionTextEdit(this); + exprTe->setMinimumHeight(50); + + // calibrate the font size + int fontsize = 12; + while (QFontMetrics(QFont("Liberation Sans",fontsize)).width("abcdef")<38 && fontsize<20) + fontsize++; + while (QFontMetrics(QFont("Liberation Sans",fontsize)).width("abcdef")>44 && fontsize>3) + fontsize--; + + exprTe->setFont(QFont("Liberation Sans",fontsize)); + + exprAndErrors->addWidget(exprTe); + + // create error widget + errorWidget=new QListWidget(); + errorWidget->setSelectionMode(QAbstractItemView::SingleSelection); + errorWidget->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Maximum)); + connect(errorWidget,SIGNAL(itemSelectionChanged()),SLOT(selectError())); + clearErrors(); + exprAndErrors->addWidget(errorWidget); + + // wire up signals + connect(exprTe, SIGNAL(applyShortcut()), SLOT(sendApply())); + connect(exprTe, SIGNAL(nextError()), SLOT(nextError())); + connect(exprTe, SIGNAL(textChanged()), SLOT(exprChanged())); + connect(controls,SIGNAL(controlChanged(int)),SLOT(controlChanged(int))); + connect(controls,SIGNAL(insertString(const std::string&)),SLOT(insertStr(const std::string&))); + connect(controlRebuildTimer, SIGNAL(timeout()), SLOT(rebuildControls())); + connect(previewTimer, SIGNAL(timeout()), SLOT(sendPreview())); +} + +void SeExprEditor::selectError() +{ + int selected=errorWidget->currentRow(); + QListWidgetItem* item=errorWidget->item(selected); + int start=item->data(Qt::UserRole).toInt(); + int end=item->data(Qt::UserRole+1).toInt(); + QTextCursor cursor=exprTe->textCursor(); + cursor.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right,QTextCursor::MoveAnchor,start); + cursor.movePosition(QTextCursor::Right,QTextCursor::KeepAnchor,end-start+1); + exprTe->setTextCursor(cursor); +} + +void SeExprEditor::sendApply() +{ + emit apply(); +} + +void SeExprEditor::sendPreview() +{ + emit preview(); +} + +void SeExprEditor::exprChanged() +{ + if (_updatingText) return; + + // schedule control rebuild + controlRebuildTimer->setSingleShot(true); + controlRebuildTimer->start(0); +} + +void SeExprEditor::rebuildControls() +{ + bool wasShown=!exprTe->completer->popup()->isHidden(); + bool newVariables=controls->rebuildControls(exprTe->toPlainText(),exprTe->completionModel->local_variables); + if(newVariables) exprTe->completer->setModel(exprTe->completionModel); + if(wasShown) exprTe->completer->popup()->show(); +} + +void SeExprEdExpressionTextEdit::updateStyle() +{ + lastStyleForHighlighter=0; + highlighter->fixStyle(palette()); + highlighter->rehighlight(); + repaint(); +} + +SeExprEdExpressionTextEdit::SeExprEdExpressionTextEdit(QWidget* parent) + :QTextEdit(parent),lastStyleForHighlighter(0),_tip(0) +{ + highlighter=new SeExprEdHighlighter(document()); + + // setup auto completion + completer=new QCompleter(); + completionModel=new SeExprEdCompletionModel(this); + completer->setModel(completionModel); + QTreeView* treePopup=new QTreeView; + completer->setPopup(treePopup); + treePopup->setRootIsDecorated(false); + treePopup->setMinimumWidth(300); + treePopup->setMinimumHeight(50); + treePopup->setItemsExpandable(true); + + completer->setWidget(this); + completer->setCompletionMode(QCompleter::PopupCompletion); + completer->setCaseSensitivity(Qt::CaseInsensitive); + QObject::connect(completer,SIGNAL(activated(const QString&)),this, + SLOT(insertCompletion(const QString&))); + + _popupEnabledAction = new QAction("Pop-up Help", this); + _popupEnabledAction->setCheckable(true); + _popupEnabledAction->setChecked(true); +} + +void SeExprEdExpressionTextEdit::focusInEvent(QFocusEvent* e) +{ + if(completer) completer->setWidget(this); + QTextEdit::focusInEvent(e); +} + +void SeExprEdExpressionTextEdit::focusOutEvent(QFocusEvent* e) +{ + hideTip(); + QTextEdit::focusInEvent(e); +} + +void SeExprEdExpressionTextEdit::mousePressEvent(QMouseEvent* event) +{ + hideTip(); + QTextEdit::mousePressEvent(event); +} + +void SeExprEdExpressionTextEdit::mouseDoubleClickEvent(QMouseEvent* event) +{ + hideTip(); + QTextEdit::mouseDoubleClickEvent(event); +} + +void SeExprEdExpressionTextEdit::paintEvent(QPaintEvent* event) +{ + if(lastStyleForHighlighter!=style()){ + lastStyleForHighlighter=style(); + highlighter->fixStyle(palette()); + highlighter->rehighlight(); + } + QTextEdit::paintEvent(event); +} + +void SeExprEdExpressionTextEdit::wheelEvent(QWheelEvent* event) +{ + if(event->modifiers() == Qt::ControlModifier){ + if(event->delta()>0) zoomIn(); + else if(event->delta()<0) zoomOut(); + } + return QTextEdit::wheelEvent(event); +} + +void SeExprEdExpressionTextEdit::keyPressEvent( QKeyEvent* e ) +{ + // Accept expression + if (e->key()==Qt::Key_Return && e->modifiers()==Qt::ControlModifier){ + emit applyShortcut(); + return ; + }else if(e->key()==Qt::Key_F4){ + emit nextError(); + return; + } + + // If the completer is active pass keys it needs down + if(completer && completer->popup()->isVisible()){ + switch(e->key()){ + case Qt::Key_Enter:case Qt::Key_Return:case Qt::Key_Escape: + case Qt::Key_Tab:case Qt::Key_Backtab: + e->ignore();return; + default: + break; + } + } + + // use the values here as long as we are not using the shortcut to bring up the editor + bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E + if (!isShortcut) // dont process the shortcut when we have a completer + QTextEdit::keyPressEvent(e); + + const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier); + if (!completer || (ctrlOrShift && e->text().isEmpty())) + return; + + bool hasModifier=(e->modifiers()!=Qt::NoModifier) && !ctrlOrShift; + + // grab the line we're on + QTextCursor tc=textCursor(); + tc.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); + QString line=tc.selectedText(); + + // matches the last prefix of a completable variable or function and extract as completionPrefix + static QRegExp completion("^(?:.*[^A-Za-z0-9_$])?((?:\\$[A-Za-z0-9_]*)|[A-Za-z]+[A-Za-z0-9_]*)$"); + int index=completion.indexIn(line); + QString completionPrefix; + if(index != -1 && !line.contains('#')){ + completionPrefix=completion.cap(1); + //std::cout<<"we have completer prefix '"<text().isEmpty() || completionPrefix.length()<1 || index==-1)){ + completer->popup()->hide(); + }else if (_popupEnabledAction->isChecked()) { + + // copy the completion prefix in if we don't already have it in the completer + if(completionPrefix!=completer->completionPrefix()){ + completer->setCompletionPrefix(completionPrefix); + completer->popup()->setCurrentIndex(completer->completionModel()->index(0,0)); + } + + // display the completer + QRect cr=cursorRect(); + cr.setWidth(completer->popup()->sizeHintForColumn(0)+completer->popup()->sizeHintForColumn(1) + + completer->popup()->verticalScrollBar()->sizeHint().width()); + cr.translate(0,6); + completer->complete(cr); + hideTip(); + return; + } + + // documentation completion + static QRegExp inFunction("^(?:.*[^A-Za-z0-9_$])?([A-Za-z0-9_]+)\\([^()]*$"); + int index2=inFunction.indexIn(line); + if(index2!=-1){ + QString functionName=inFunction.cap(1); + QStringList tips=completionModel->getDocString(functionName).split("\n"); + QString tip=""+tips[0]+""; + for(int i=1;iisChecked()) showTip(tip); + //QToolTip::showText(mapToGlobal(cr.bottomLeft()),tip,this,cr); + }else{ + hideTip(); + } +} + +void SeExprEdExpressionTextEdit::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu *menu = createStandardContextMenu(); + + if (!menu->actions().empty()) + { + QAction* f = menu->actions().first(); + menu->insertAction(f, _popupEnabledAction); + menu->insertSeparator(f); + } + + menu->exec(event->globalPos()); + delete menu; +} + +void SeExprEdExpressionTextEdit::showTip(const QString& string) +{ + // skip empty strings + if(string=="") return; + // skip already shown stuff + if(_tip && !_tip->isHidden() && _tip->label->text() == string) return; + + QRect cr=cursorRect(); + cr.setX(0); + cr.setWidth(cr.width()*3); + if(_tip){delete _tip;_tip=0;} + _tip=new SeExprEdPopupDocumentation(this,mapToGlobal(cr.bottomLeft())+QPoint(0,6),string); +} + +void SeExprEdExpressionTextEdit::hideTip() +{ + if(_tip) _tip->hide(); +} + +void SeExprEdExpressionTextEdit::insertCompletion(const QString &completion) +{ + if (completer->widget() != this) return; + QTextCursor tc = textCursor(); + int extra = completion.length() - completer->completionPrefix().length(); + tc.movePosition(QTextCursor::Left); + tc.movePosition(QTextCursor::EndOfWord); + tc.insertText(completion.right(extra)); + if(completion[0]!='$') tc.insertText("("); + setTextCursor(tc); +} + +std::string SeExprEditor::getExpr() +{ + return exprTe->toPlainText().toStdString(); +} + +void SeExprEditor::setExpr(const std::string& expression,const bool doApply) +{ + //exprTe->clear(); + exprTe->selectAll(); + exprTe->insertPlainText(QString::fromStdString(expression)); + clearErrors(); + exprTe->moveCursor(QTextCursor::Start); + if(doApply) emit apply(); +} + +void SeExprEditor::insertStr(const std::string& str) +{ + exprTe->insertPlainText(QString::fromStdString(str)); +} + +void SeExprEditor::appendStr(const std::string& str) +{ + exprTe->append(QString::fromStdString(str)); +} + +void SeExprEditor::addError(const int startPos,const int endPos,const std::string& error) +{ + QListWidgetItem* item=new QListWidgetItem(("Error: "+error).c_str(),errorWidget); + item->setData(Qt::UserRole,startPos); + item->setData(Qt::UserRole+1,endPos); + errorWidget->setHidden(false); + // TODO: fix to not use count lines and compute heuristic of 25 pixels per line! + const char* c=error.c_str(); + int lines=1; + while(*c != '\0'){ + if(*c == '\n') lines++; + c++; + } + errorHeight+=25*lines; + // widget should not need to be bigger than this + errorWidget->setMaximumHeight(errorHeight); +} + +void SeExprEditor::nextError() +{ + int newRow=errorWidget->currentRow()+1; + if(newRow>=errorWidget->count()) newRow=0; + errorWidget->setCurrentRow(newRow); +} + +void SeExprEditor::clearErrors() +{ + errorWidget->clear(); + errorWidget->setHidden(true); + errorHeight=0; +} + +void SeExprEditor::clearExtraCompleters() +{ + exprTe->completionModel->clearFunctions(); + exprTe->completionModel->clearVariables(); +} + +void SeExprEditor::registerExtraFunction(const std::string& name,const std::string& docString) +{ + exprTe->completionModel->addFunction(name.c_str(),docString.c_str()); +} + +void SeExprEditor::registerExtraVariable(const std::string& name,const std::string& docString) +{ + exprTe->completionModel->addVariable(name.c_str(),docString.c_str()); +} + +void SeExprEditor::replaceExtras(const SeExprEdCompletionModel& completer) +{ + exprTe->completionModel->syncExtras(completer); +} + +void SeExprEditor::updateCompleter() +{ + exprTe->completer->setModel(exprTe->completionModel); +} + +void SeExprEditor::updateStyle() +{ + exprTe->updateStyle(); +} + diff --git a/src/SeExprEditor/SeExprEditor.h b/src/SeExprEditor/SeExprEditor.h new file mode 100644 index 00000000..d1abb43a --- /dev/null +++ b/src/SeExprEditor/SeExprEditor.h @@ -0,0 +1,158 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* @file SeExprEditor.h +* @brief This provides an expression editor for SeExpr syntax with auto ui features +* @author aselle +*/ +#ifndef SeExprEditor_h +#define SeExprEditor_h + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +class QLabel; +class QPushButton; +class QLineEdit; +class QMouseEvent; +class QPaintEvent; +class QKeyEvent; +class QCompleter; +class QToolTip; +class QListWidget; +class QListWidgetItem; +class SeExprEdCompletionModel; +class SeExprEdControl; +class SeExprEdControlCollection; + + +class SeExprEditor; +class SeExprCompletionModel; +class SeExprEdHighlighter; +class SeExprEdPopupDocumentation; + +class SeExprEdExpressionTextEdit : public QTextEdit +{ + Q_OBJECT + + QToolTip* functionTip; + std::map functionTooltips; + SeExprEdHighlighter* highlighter; + QStyle* lastStyleForHighlighter; + SeExprEdPopupDocumentation* _tip; + QAction* _popupEnabledAction; + public: + QCompleter* completer; + SeExprEdCompletionModel* completionModel; + + + public: + SeExprEdExpressionTextEdit(QWidget* parent = 0); + ~SeExprEdExpressionTextEdit(); + void updateStyle(); + + protected: + void showTip(const QString& string); + void hideTip(); + + virtual void keyPressEvent(QKeyEvent* e); + void focusInEvent(QFocusEvent* e); + void focusOutEvent(QFocusEvent* e); + void mousePressEvent(QMouseEvent* event); + void mouseDoubleClickEvent(QMouseEvent* event); + void paintEvent(QPaintEvent* e); + void wheelEvent(QWheelEvent* e); + void contextMenuEvent(QContextMenuEvent* event); + + private slots: + void insertCompletion(const QString& completion); + signals: + void applyShortcut(); + void nextError(); + +}; + + +class SeExprEditor : public QWidget +{ + Q_OBJECT + + public: + SeExprEditor(QWidget* parent,SeExprEdControlCollection* controls); + virtual ~SeExprEditor(); + + public slots: + void exprChanged(); + void rebuildControls(); + void controlChanged(int id); + void nextError(); + void selectError(); + void sendApply(); + void sendPreview(); + //void handlePreviewTimer(); + signals: + void apply(); + void preview(); + public: + // Get the expression that is in the editor + std::string getExpr(); + // Sets the expression that is in the editor + void setExpr(const std::string& expression,const bool apply=false); + // Append string + void appendStr(const std::string& str); + public slots: + // Insert string + void insertStr(const std::string& str); + public: + // Adds an error and its associated position + void addError(const int startPos,const int endPos,const std::string& error); + // Removes all errors and hides the completion widget + void clearErrors(); + // Removes all extra completion symbols + void clearExtraCompleters(); + // Registers an extra function and associated do cstring + void registerExtraFunction(const std::string& name,const std::string& docString); + // Register an extra variable (i.e. $P, or $u, something provided by resolveVar) + void registerExtraVariable(const std::string& name,const std::string& docString); + // Replace extras + void replaceExtras(const SeExprEdCompletionModel& completer); + // Updates the completion widget, must call after registering any new functions/variables + void updateCompleter(); + // Updates style + void updateStyle(); + private: + SeExprEdExpressionTextEdit* exprTe; + SeExprEdControlCollection* controls; + QListWidget* errorWidget; + + QTimer* controlRebuildTimer; + QTimer* previewTimer; + + + bool _updatingText; + int errorHeight; + +}; + +#endif diff --git a/src/SeExprEditor/SeExprSpecParser.y b/src/SeExprEditor/SeExprSpecParser.y new file mode 100644 index 00000000..e25ceb34 --- /dev/null +++ b/src/SeExprEditor/SeExprSpecParser.y @@ -0,0 +1,495 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ + +%{ +#include +#include +#include +#include +#include +#include +#ifdef SEEXPR_USE_ANIMLIB +#include +#include +#else +#define UNUSED(x) (void)(x) +#endif +#include "SePlatform.h" +#include "SeExprSpecType.h" +#include "SeExprEdEditable.h" + + +/****************** + lexer declarations + ******************/ + + +#define SPEC_IS_NUMBER(x) \ + (dynamic_cast(x) != 0) +#define SPEC_IS_VECTOR(x) \ + (dynamic_cast(x) != 0) +#define SPEC_IS_STR(x) \ + (dynamic_cast(x) != 0) + +// declarations of functions and data in SeExprParser.l +int yylex(); +int yypos(); +extern int yy_start; +extern char* yytext; +struct yy_buffer_state; +yy_buffer_state* yy_scan_string(const char *str); +void yy_delete_buffer(yy_buffer_state*); + +//##################################### +// Keep track of mini parse tree nodes + +// temporary to the parse... all pointers deleted at end of parse +static std::vector specNodes; +/// Remember the spec node, so we can delete it later +SeExprSpecNode* remember(SeExprSpecNode* node) +{specNodes.push_back(node);return node;} + + +/// list of strings duplicated by lexer to avoid error mem leak +static std::vector tokens; + +char* specRegisterToken(char* rawString) +{ + char* tok=strdup(rawString); + tokens.push_back(tok); + return tok; +} + +//###################################################################### +// Expose parser API inputs/outputs to yacc as statics + +// these are pointers to the arguments send into parse API +// made static here so the parser can see them in yacc actions +static std::vector* editables; +static std::vector* variables; + +static const char* ParseStr; // string being parsed +static std::string ParseError; // error (set from yyerror) +static SeExprSpecNode* ParseResult; // must set result here since yyparse can't return it + + +//###################################################################### +// Helpers used by actions to register data + + +/// Remember that there is an assignment to this variable (For autocomplete) +void registerVariable(const char* var) +{ + variables->push_back(var); +} + +/// Variable Assignment/String literal should be turned into an editable +/// an editable is the data part of a control (it's model essentially) +void registerEditable(const char* var,SeExprSpecNode* node) +{ + //std::cerr<<"we have editable var "<(node)){ + editables->push_back(new SeExprEdNumberEditable(var,node->startPos,node->endPos,n->v)); + }else if(SeExprSpecVectorNode* n=dynamic_cast(node)){ + editables->push_back(new SeExprEdVectorEditable(var,node->startPos,node->endPos,n->v)); + }else if(SeExprSpecStringNode* n=dynamic_cast(node)){ + editables->push_back(new SeExprEdStringEditable(node->startPos,node->endPos,n->v)); + }else if(SeExprSpecCCurveNode* n=dynamic_cast(node)){ + if(SeExprSpecListNode* args=dynamic_cast(n->args)){ + if((args->nodes.size())%3==0){ + SeExprEdColorCurveEditable* ccurve=new SeExprEdColorCurveEditable(var,node->startPos,node->endPos); + bool valid=true; + for(size_t i=0;inodes.size();i+=3){ + SeExprSpecScalarNode* xnode=dynamic_cast(args->nodes[i]); + SeExprSpecVectorNode* ynode=dynamic_cast(args->nodes[i+1]); + SeExprSpecScalarNode* interpnode=dynamic_cast(args->nodes[i+2]); + if(xnode && ynode && interpnode){ + ccurve->add(xnode->v,ynode->v,interpnode->v); + }else{ + valid=false; + } + } + if(valid) editables->push_back(ccurve); + else delete ccurve; + }else{ + //std::cerr<<"Curve has wrong # of args"<nodes.size()<(node)){ + if(SeExprSpecListNode* args=dynamic_cast(n->args)){ + if((args->nodes.size())%3==0){ + SeExprEdCurveEditable* ccurve=new SeExprEdCurveEditable(var,node->startPos,node->endPos); + bool valid=true; + for(size_t i=0;inodes.size();i+=3){ + SeExprSpecScalarNode* xnode=dynamic_cast(args->nodes[i]); + SeExprSpecScalarNode* ynode=dynamic_cast(args->nodes[i+1]); + SeExprSpecScalarNode* interpnode=dynamic_cast(args->nodes[i+2]); + if(xnode && ynode && interpnode){ + ccurve->add(xnode->v,ynode->v,interpnode->v); + }else{ + valid=false; + } + } + if(valid) editables->push_back(ccurve); + else{ + delete ccurve; + } + } + } + }else if(SeExprSpecAnimCurveNode* n=dynamic_cast(node)){ + if(SeExprSpecListNode* args=dynamic_cast(n->args)){ + // need 3 items for pre inf and post inf and weighting, plus 9 items per key + if((args->nodes.size()-4)%9==0){ + SeExprEdAnimCurveEditable* animCurve=new SeExprEdAnimCurveEditable(var,node->startPos,node->endPos); + bool valid=true; + + +#ifdef SEEXPR_USE_ANIMLIB + if(SeExprSpecStringNode* s=dynamic_cast(args->nodes[0])){ + animCurve->curve.setPreInfinity(animlib::AnimCurve::stringToInfinityType(s->v)); + }else valid=false; + if(SeExprSpecStringNode* s=dynamic_cast(args->nodes[1])){ + animCurve->curve.setPostInfinity(animlib::AnimCurve::stringToInfinityType(s->v)); + }else valid=false; + if(SeExprSpecScalarNode* v=dynamic_cast(args->nodes[2])){ + animCurve->curve.setWeighted(bool(v->v)); + } + if(SeExprSpecStringNode* v=dynamic_cast(args->nodes[3])){ + animCurve->link=v->v; + } + + for(size_t i=4;inodes.size();i+=9){ + SeExprSpecScalarNode* xnode=dynamic_cast(args->nodes[i]); + SeExprSpecScalarNode* ynode=dynamic_cast(args->nodes[i+1]); + SeExprSpecScalarNode* inWeight=dynamic_cast(args->nodes[i+2]); + SeExprSpecScalarNode* outWeight=dynamic_cast(args->nodes[i+3]); + SeExprSpecScalarNode* inAngle=dynamic_cast(args->nodes[i+4]); + SeExprSpecScalarNode* outAngle=dynamic_cast(args->nodes[i+5]); + SeExprSpecStringNode* inTangType=dynamic_cast(args->nodes[i+6]); + SeExprSpecStringNode* outTangType=dynamic_cast(args->nodes[i+7]); + SeExprSpecScalarNode* weighted=dynamic_cast(args->nodes[i+8]); + if(xnode && ynode && inWeight && outWeight && inAngle && outAngle && inTangType && outTangType ){ + animlib::AnimKeyframe key(xnode->v,ynode->v); + key.setInWeight(inWeight->v); + key.setOutWeight(outWeight->v); + key.setInAngle(inAngle->v); + key.setOutAngle(outAngle->v); + key.setInTangentType(animlib::AnimKeyframe::stringToTangentType(inTangType->v)); + key.setOutTangentType(animlib::AnimKeyframe::stringToTangentType(outTangType->v)); + key.setWeightsLocked(weighted->v); + animCurve->curve.addKey(key); + }else{ + valid=false; + } + } + if(valid) editables->push_back(animCurve); + else delete animCurve; +#else + UNUSED(animCurve); + UNUSED(valid); +#endif + } + } + }else{ + std::cerr<<"SEEXPREDITOR LOGIC ERROR: We didn't recognize the Spec"< NAME VAR STR +%token NUMBER +%token AddEq SubEq MultEq DivEq ExpEq ModEq +%token '(' ')' +%left ARROW +%nonassoc ':' +%nonassoc '?' +%left OR +%left AND +%left EQ NE +%left '<' '>' LE GE +%left '+' '-' +%left '*' '/' '%' +%right UNARY '!' '~' +%right '^' +%left '[' +%type optassigns assigns assign ifthenelse optelse e optargs args arg + +/* Some notes about the parse tree construction: + + Each rule first parses its children and then returns a new node + that implements the particular rule (an arithmetic op, a function + call, or whatever). Sometimes the child node is just passed up (in + the case of a parenthesized expression or a unary '+' for + instance). But in all cases, a rule returns a parse node which + represents a complete sub-tree. Finally, the "expr" rule returns + the root node which represents the completed parse tree. +*/ +%% + +// TODO: Change grammar to have option to choose to allow variables of the form +// $foo or foo. Currently we allow either. + +/* The root expression rule */ +expr: + assigns e { ParseResult = 0; } + | e { ParseResult = 0; } + ; + +/* local variable assignments */ +optassigns: + /* empty */ { $$ = 0; } + | assigns { $$ = 0; } + ; + +assigns: + assign { $$ = 0; } + | assigns assign { $$ = 0; } + ; + + +assign: + ifthenelse { $$ = 0; } + | VAR '=' e ';' { + registerVariable($1); + registerEditable($1,$3); + } + | VAR AddEq e ';' { $$ = 0; } + | VAR SubEq e ';' { $$ = 0; } + | VAR MultEq e ';' { $$ = 0; } + | VAR DivEq e ';' { $$ = 0; } + | VAR ExpEq e ';' { $$ = 0; } + | VAR ModEq e ';' { $$ = 0; } + | NAME '=' e ';' { + registerVariable($1); + registerEditable($1,$3); + } + | NAME AddEq e ';' { $$ = 0; } + | NAME SubEq e ';' { $$ = 0; } + | NAME MultEq e ';' { $$ = 0; } + | NAME DivEq e ';' { $$ = 0; } + | NAME ExpEq e ';' { $$ = 0; } + | NAME ModEq e ';' { $$ = 0; } + ; + +ifthenelse: + IF '(' e ')' '{' optassigns '}' optelse + { $$ = 0; } + ; + +optelse: +/* empty */ { $$ = 0; } +| ELSE '{' optassigns '}' { $$ = 0;} +| ELSE ifthenelse { $$ = 0;} + ; + +/* An expression or sub-expression */ +e: + '(' e ')' { $$ = 0; } + | '[' e ',' e ',' e ']' { + if(SPEC_IS_NUMBER($2) && SPEC_IS_NUMBER($4) && SPEC_IS_NUMBER($6)){ + $$=remember(new SeExprSpecVectorNode(@$.first_column,@$.last_column,$2,$4,$6)); + }else $$=0; + } + | e '[' e ']' { $$ = 0; } + | e '?' e ':' e { $$ = 0; } + | e OR e { $$ = 0; } + | e AND e { $$ = 0; } + | e EQ e { $$ = 0; } + | e NE e { $$ = 0; } + | e '<' e { $$ = 0; } + | e '>' e { $$ = 0; } + | e LE e { $$ = 0; } + | e GE e { $$ = 0; } + | '+' e %prec UNARY { $$ = $2; } + | '-' e %prec UNARY { + if(SPEC_IS_NUMBER($2)){ + SeExprSpecScalarNode* node=(SeExprSpecScalarNode*)$2; + node->v*=-1; + node->startPos=@$.first_column; + node->endPos=@$.last_column; + $$=$2; + }else $$=0; + } + | '!' e { $$ = 0; } + | '~' e { $$ = 0; } + | e '+' e { $$ = 0; } + | e '-' e { $$ = 0; } + | e '*' e { $$ = 0; } + | e '/' e { $$ = 0; } + | e '%' e { $$ = 0; } + | e '^' e { $$ = 0; } + | NAME '(' optargs ')' { + if($3 && strcmp($1,"curve")==0){ + $$=remember(new SeExprSpecCurveNode($3)); + }else if($3 && strcmp($1,"ccurve")==0){ + $$=remember(new SeExprSpecCCurveNode($3)); + }else if($3 && strcmp($1,"animCurve")==0){ + $$=remember(new SeExprSpecAnimCurveNode($3)); + }else if($3){ + // function arguments not parse of curve, ccurve, or animCurve + // check if there are any string args that need to be made into controls + // but be sure to return 0 as this parseable + if(SeExprSpecListNode* list=dynamic_cast($3)){ + for(size_t i=0;inodes.size();i++){ + if(SeExprSpecStringNode* str=dynamic_cast(list->nodes[i])){ + registerEditable("",str); + } + } + } + $$=0; + }else $$=0; + } + | e ARROW NAME '(' optargs ')'{$$ = 0; } + | VAR { $$ = 0; } + | NAME { $$ = 0; } + | NUMBER { $$=remember(new SeExprSpecScalarNode(@$.first_column,@$.last_column,$1)); } + ; + +/* An optional argument list */ +optargs: + /* empty */ { $$ = 0;} + | args { $$ = $1;} + ; + +/* Argument list (comma-separated expression list) */ +args: + arg { + // ignore first argument unless it is a string (because we parse strings in weird ways) + SeExprSpecListNode* list=new SeExprSpecListNode(@$.last_column,@$.last_column); + if($1 && SPEC_IS_STR($1)){ + list->add($1); + } + remember(list); + $$=list; + } + | args ',' arg { + + if($1 && $3 && ((SPEC_IS_NUMBER($3) || SPEC_IS_VECTOR($3) || SPEC_IS_STR($3)))){ + $$=$1; + dynamic_cast($1)->add($3); + }else{ + $$=0; + } + } + ; + +arg: + e { $$ = $1;} + | STR { + SeExprSpecStringNode* str=new SeExprSpecStringNode(@$.first_column,@$.last_column,$1); + //registerEditable("",str); + // TODO: move string stuff out + $$ = remember(str); + } + ; + +%% + + /* yyerror - Report an error. This is called by the parser. + (Note: the "msg" param is useless as it is usually just "sparse error". + so it's ignored.) + */ +static void yyerror(const char* /*msg*/) +{ + // find start of line containing error + int pos = yypos(), lineno = 1, start = 0, end = strlen(ParseStr); + bool multiline = 0; + for (int i = start; i < pos; i++) + if (ParseStr[i] == '\n') { start = i + 1; lineno++; multiline=1; } + + // find end of line containing error + for (int i = end; i > pos; i--) + if (ParseStr[i] == '\n') { end = i - 1; multiline=1; } + + ParseError = yytext[0] ? "Syntax error" : "Unexpected end of expression"; + if (multiline) { + char buff[30]; + snprintf(buff, 30, " at line %d", lineno); + ParseError += buff; + } + if (yytext[0]) { + ParseError += " near '"; + ParseError += yytext; + } + ParseError += "':\n "; + + int s = std::max(start, pos-30); + int e = std::min(end, pos+30); + + if (s != start) ParseError += "..."; + ParseError += std::string(ParseStr, s, e-s+1); + if (e != end) ParseError += "..."; +} + +extern void resetCounters(std::vector >& comments); + + +/* CallParser - This is our entrypoint from the rest of the expr library. + A string is passed in and a parse tree is returned. If the tree is null, + an error string is returned. Any flags set during parsing are passed + along. + */ + +//static Mutex mutex; + +/// Main entry point to parser +bool SeExprParse(std::vector& outputEditables, + std::vector& outputVariables, + std::vector >& comments, + const char* str) +{ + // TODO: this needs a mutex! + + /// Make inputs/outputs accessible to parser actions + editables=&outputEditables; + variables=&outputVariables; + ParseStr=str; + + // setup and startup parser + resetCounters(comments); // reset lineNumber and columnNumber in scanner + yy_buffer_state* buffer = yy_scan_string(str); // setup lexer + ParseResult = 0; + int resultCode = yyparse(); // parser (don't care if it is a parse error) + UNUSED(resultCode); + yy_delete_buffer(buffer); + + // delete temporary data -- specs(mini parse tree) and tokens(strings)! + for(size_t i=0;i +# include +# include +#define _USE_MATH_DEFINES +# include +#endif + +//#include "SePlatform.h" +//#include "SeExprSpecParser.h" +#include "SeExprSpecType.h" + +#ifdef SEEXPR_WIN32 +# define YY_NO_UNISTD_H +# define YY_SKIP_YYWRAP +#endif + +#ifndef MAKEDEPEND +# include "SeExprSpecParser.tab.h" +#endif + +// TODO: make this thread safe +static int columnNumber=0; // really buffer position +static int lineNumber=0; // not used + +static std::vector >* comments=0; + +extern char* specRegisterToken(char* tok); +void resetCounters(std::vector >& commentsIn){ + columnNumber=lineNumber=0; + comments=&commentsIn; +} + +int yypos(); // forward declare + + +#define YY_USER_ACTION { \ + yylloc.first_line=lineNumber;yylloc.first_column=columnNumber; \ + columnNumber+=yyleng;\ + yylloc.last_column=columnNumber;yylloc.last_line=lineNumber;} + +%} + +D [0-9] +E [Ee][+-]?{D}+ +REAL {D}+({E})?|{D}*"."{D}+({E})?|{D}+"."{D}*({E})? +IDENT [a-zA-Z_][a-zA-Z0-9_.]* + +%% +BEGIN(0); + +if { return IF; } +else { return ELSE; } + +"||" { return OR; } +"&&" { return AND; } +"==" { return EQ; } +"!=" { return NE; } +"<=" { return LE; } +">=" { return GE; } +"->" { return ARROW; } +"+=" { return AddEq; } +"-=" { return SubEq; } +"*=" { return MultEq; } +"/=" { return DivEq; } +"%=" { return ModEq; } +"^=" { return ExpEq; } + +PI { yylval.d = M_PI; return NUMBER; } +E { yylval.d = M_E; return NUMBER; } +linear { yylval.d = 0; return NUMBER; } +smooth { yylval.d = 1; return NUMBER; } +gaussian { yylval.d = 2; return NUMBER; } +box { yylval.d = 3; return NUMBER; } + +{REAL} { yylval.d = atof(yytext); return NUMBER; } +\"(\\\"|[^"\n])*\" { /* match quoted string, allow embedded quote, \" */ + yylval.s = specRegisterToken(&yytext[1]); + yylval.s[strlen(yylval.s)-1] = '\0'; + return STR; } +\'(\\\'|[^'\n])*\' { /* match quoted string, allow embedded quote, \' */ + yylval.s = specRegisterToken(&yytext[1]); + yylval.s[strlen(yylval.s)-1] = '\0'; + return STR; } +${IDENT} { yylval.s = specRegisterToken(&yytext[1]); return VAR; } +${IDENT}"::"{IDENT} { yylval.s = specRegisterToken(&yytext[1]); return VAR; } +{IDENT} { yylval.s = specRegisterToken(yytext); return NAME; } + +"\\n" /* ignore quoted newline */; +"\\t" /* ignore quoted tab */; +[ \t\n] /* ignore whitespace */; +\#([^\\\n]|\\[^n\n])* { /* match comment */ + int startPos=yypos(),endPos=yypos()+strlen(&yytext[1])+1; + comments->push_back(std::pair(startPos,endPos));} + + +<*>. { return yytext[0]; } + +%% + +/* Gets index of current token (corresponding to yytext). + Used for error reporting. + */ +int yypos() +{ + return yy_c_buf_p - YY_CURRENT_BUFFER->yy_ch_buf - yyleng; +} diff --git a/src/SeExprEditor/SeExprSpecType.h b/src/SeExprEditor/SeExprSpecType.h new file mode 100644 index 00000000..db2fa292 --- /dev/null +++ b/src/SeExprEditor/SeExprSpecType.h @@ -0,0 +1,121 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef _SeExprSpecType_h_ +#define _SeExprSpecType_h_ + +#include +#include +#include +#include +#include + +/// Mini parse tree node... Only represents literals, and lists of literals +struct SeExprSpecNode +{ + int startPos,endPos; + + + SeExprSpecNode(int startPos,int endPos) + :startPos(startPos),endPos(endPos) + {} + + virtual ~SeExprSpecNode() + {} +}; + +struct SeExprSpecScalarNode:public SeExprSpecNode +{ + double v; + + SeExprSpecScalarNode(int startPos,int endPos,double scalar) + :SeExprSpecNode(startPos,endPos),v(scalar) + {} +}; + +struct SeExprSpecVectorNode:public SeExprSpecNode +{ + SeVec3d v; + SeExprSpecVectorNode(int startPos,int endPos,SeExprSpecNode* x,SeExprSpecNode* y,SeExprSpecNode* z) + :SeExprSpecNode(startPos,endPos) + { + v=SeVec3d(static_cast(x)->v,static_cast(y)->v,static_cast(z)->v); + } + +}; + +struct SeExprSpecListNode:public SeExprSpecNode +{ + std::vector nodes; + SeExprSpecListNode(int startPos,int endPos) + :SeExprSpecNode(startPos,endPos) + {} + + void add(SeExprSpecNode* node){ + startPos=std::min(node->startPos,startPos); + endPos=std::max(node->endPos,endPos); + nodes.push_back(node); + } +}; + +struct SeExprSpecStringNode:public SeExprSpecNode +{ + std::string v; + SeExprSpecStringNode(int startPos,int endPos,const char* s) + :SeExprSpecNode(startPos,endPos),v(s) + {} +}; + +struct SeExprSpecCurveNode:public SeExprSpecNode +{ + SeExprSpecNode* args; + SeExprSpecCurveNode(SeExprSpecNode* args) + :SeExprSpecNode(args->startPos,args->endPos),args(args) + {} +}; + +struct SeExprSpecCCurveNode:public SeExprSpecNode +{ + SeExprSpecNode* args; + SeExprSpecCCurveNode(SeExprSpecNode* args) + :SeExprSpecNode(args->startPos,args->endPos),args(args) + {} +}; + +struct SeExprSpecAnimCurveNode:public SeExprSpecNode +{ + SeExprSpecNode* args; + SeExprSpecAnimCurveNode(SeExprSpecNode* args) + :SeExprSpecNode(args->startPos,args->endPos),args(args) + {} +}; + + + + + + +#endif + + + + + + + + + + diff --git a/src/SeExprEditor/SeExpressionEditor.cpp b/src/SeExprEditor/SeExpressionEditor.cpp new file mode 100644 index 00000000..bc6e022e --- /dev/null +++ b/src/SeExprEditor/SeExpressionEditor.cpp @@ -0,0 +1,45 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ + +#include +#include + +#include +#include "SeExprEdDialog.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + SeExprEdDialog dialog(0); + dialog.setWindowTitle("Expression Editor"); + dialog.show(); + + if (argc < 2 || std::string(argv[1]) != "-automatedTest") { + if (dialog.exec() == QDialog::Accepted) + std::cerr << "returned expression: " << dialog.getExpressionString() << std::endl; + } else { + std::string str = "$u + $v"; + dialog.setExpressionString(str); + if (dialog.getExpressionString() != str ) { + std::cerr << "test failed: " << dialog.getExpressionString() << " != " << str << std::endl; + return 1; + } + } + + return 0; +} + diff --git a/src/SeExprEditor/generated/README b/src/SeExprEditor/generated/README new file mode 100644 index 00000000..e11f8dbc --- /dev/null +++ b/src/SeExprEditor/generated/README @@ -0,0 +1,2 @@ +If you copy the files from here from a Linux machine to a Windows machime, you +don't need flex/bison on the Windows machine to build SeExpr diff --git a/src/build/macros.cmake b/src/build/macros.cmake new file mode 100644 index 00000000..ba59f485 --- /dev/null +++ b/src/build/macros.cmake @@ -0,0 +1,60 @@ + +macro(BuildParserScanner FLEX_L_PREFIX BISON_Y_PREFIX PARSER_PREFIX GENERATED_CPPS) + ## find our parser generators + find_program(BISON_EXE bison) + find_program(FLEX_EXE flex) + find_program(SED_EXE sed) + + if((BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) + # don't have flex/bison/sed, use pregenerated versions + set (${GENERATED_CPPS} generated/${BISON_Y_PREFIX}.cpp generated/${FLEX_L_PREFIX}.cpp ) + else ((BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) + ## build the parser from the flex/yacc sources + + ADD_CUSTOM_COMMAND( + SOURCE "${FLEX_L_PREFIX}.l" + COMMAND "flex" + ARGS "-o${FLEX_L_PREFIX}In.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/${FLEX_L_PREFIX}.l" + OUTPUT ${FLEX_L_PREFIX}In.cpp + DEPENDS ${FLEX_L_PREFIX}.l + ) + + ADD_CUSTOM_COMMAND( + SOURCE "${FLEX_L_PREFIX}In.cpp" + COMMAND "sed" + ARGS -e "'s/${PARSER_PREFIX}wrap(n)/${PARSER_PREFIX}wrap()/g'" -e "'s/yy/${PARSER_PREFIX}/g'" -e "'s/YY/${PARSER_PREFIX}YY/g'" ${FLEX_L_PREFIX}In.cpp | tee ${FLEX_L_PREFIX}.cpp ${CMAKE_CURRENT_SOURCE_DIR}/generated/${FLEX_L_PREFIX}.cpp > /dev/null + OUTPUT ${FLEX_L_PREFIX}.cpp + DEPENDS ${FLEX_L_PREFIX}In.cpp + ) + + ADD_CUSTOM_COMMAND( + SOURCE "${BISON_Y_PREFIX}.y" + COMMAND "bison" + ARGS "--defines" "--verbose" "--fixed-output-files" "-p" "${PARSER_PREFIX}" "${CMAKE_CURRENT_SOURCE_DIR}/${BISON_Y_PREFIX}.y" + OUTPUT y.tab.c y.tab.h + DEPENDS ${BISON_Y_PREFIX}.y + ) + + ADD_CUSTOM_COMMAND( + SOURCE "y.tab.h" + COMMAND "sed" + ARGS -e "'s/yy/${PARSER_PREFIX}/g'" -e "'s/YY/${PARSER_PREFIX}YY/g'" y.tab.h | tee ${BISON_Y_PREFIX}.tab.h ${CMAKE_CURRENT_SOURCE_DIR}/generated/${BISON_Y_PREFIX}.tab.h > /dev/null + OUTPUT ${BISON_Y_PREFIX}.tab.h + DEPENDS y.tab.h + ) + + ADD_CUSTOM_COMMAND( + SOURCE "y.tab.c" + COMMAND "sed" + ARGS -e "'s/yy/${PARSER_PREFIX}/g'" -e "'s/YY/${PARSER_PREFIX}YY/g'" y.tab.c | tee ${BISON_Y_PREFIX}.cpp "${CMAKE_CURRENT_SOURCE_DIR}/generated/${BISON_Y_PREFIX}.cpp" > /dev/null + OUTPUT ${BISON_Y_PREFIX}.cpp + DEPENDS y.tab.c ${BISON_Y_PREFIX}.tab.h + ) + + ## set build files + set (${GENERATED_CPPS} ${FLEX_L_PREFIX}.cpp ${BISON_Y_PREFIX}.cpp) + #add_custom_target(run ALL DEPENDS ${${GENERATED_CPPS}}) + endif( (BISON_EXE STREQUAL "BISON_EXE-NOTFOUND") OR (FLEX_EXE STREQUAL "FLEX_EXE-NOTFOUND") OR (SED_EXE STREQUAL "SED_EXE-NOTFOUND")) + + +endmacro() diff --git a/src/demos/CMakeLists.txt b/src/demos/CMakeLists.txt index ae52a31c..8fb8eaea 100644 --- a/src/demos/CMakeLists.txt +++ b/src/demos/CMakeLists.txt @@ -1,35 +1,18 @@ -# SEEXPR SOFTWARE -# Copyright 2011 Disney Enterprises, Inc. All rights reserved -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation -# Studios" or the names of its contributors may NOT be used to -# endorse or promote products derived from this software without -# specific prior written permission from Walt Disney Pictures. -# -# Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -# IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 ADD_EXECUTABLE(asciiGraph "asciiGraph.cpp") target_link_libraries(asciiGraph ${SEEXPR_LIBRARIES}) @@ -42,5 +25,6 @@ install(TARGETS asciiCalc DESTINATION bin) ADD_SUBDIRECTORY (imageSynth) +ADD_SUBDIRECTORY (imageEditor) ADD_SUBDIRECTORY (segraph) ADD_SUBDIRECTORY (rman) diff --git a/src/demos/asciiCalculator.cpp b/src/demos/asciiCalculator.cpp index 5cac6dc2..5ecbc253 100644 --- a/src/demos/asciiCalculator.cpp +++ b/src/demos/asciiCalculator.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #include #include diff --git a/src/demos/asciiGraph.cpp b/src/demos/asciiGraph.cpp index 0f4f3f83..25e800ab 100644 --- a/src/demos/asciiGraph.cpp +++ b/src/demos/asciiGraph.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #include #include diff --git a/src/demos/imageEditor/CMakeLists.txt b/src/demos/imageEditor/CMakeLists.txt new file mode 100644 index 00000000..103b59d9 --- /dev/null +++ b/src/demos/imageEditor/CMakeLists.txt @@ -0,0 +1,44 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + +# Set application root dir for use inside the source code. +cmake_policy(SET CMP0005 NEW) +add_definitions(-DIMAGE_EDITOR_ROOT="${CMAKE_INSTALL_PREFIX}") + +find_package(Qt4 COMPONENTS QtCore QtGui) # find and setup Qt4 for this project +if(QT4_FOUND) + set(imageEditor_MOC_HDRS ImageEditorDialog.h) + set(imageEditor_CPPS imageEditor.cpp) + qt4_wrap_cpp(imageEditor_MOC_SRCS ${imageEditor_MOC_HDRS}) + + add_executable(imageEditor ${imageEditor_CPPS} ${imageEditor_MOC_SRCS}) + include_directories(${QT_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) + include_directories(${SEEXPR_EDITOR_INCLUDES}) + target_link_libraries(imageEditor ${QT_QTCORE_LIBRARY}) + target_link_libraries(imageEditor ${QT_QTGUI_LIBRARY}) + target_link_libraries(imageEditor ${SEEXPR_LIBRARIES}) + target_link_libraries(imageEditor ${SEEXPR_EDITOR_LIBRARIES}) +endif(QT4_FOUND) + +FIND_PACKAGE(PNG) +IF(PNG_FOUND) + INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR}) + TARGET_LINK_LIBRARIES(imageEditor ${PNG_LIBRARIES}) + install(TARGETS imageEditor DESTINATION bin) +ENDIF(PNG_FOUND) + +INSTALL( FILES fbm.se noisecolor1.se noisecolor2.se noise.se raytrace.se sinc.se DESTINATION ${CMAKE_INSTALL_PREFIX}/expressions/ ) + diff --git a/src/demos/imageEditor/ImageEditorDialog.h b/src/demos/imageEditor/ImageEditorDialog.h new file mode 100644 index 00000000..913c679b --- /dev/null +++ b/src/demos/imageEditor/ImageEditorDialog.h @@ -0,0 +1,39 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ + +/** + @file ImageEditorDialog.h +*/ + +#include + +class QLabel; +class SeExprEditor; +class ImageSynthesizer; + +class ImageEditorDialog: public QDialog +{ + Q_OBJECT +public: + ImageEditorDialog(QWidget *parent=0); +private: + QLabel *_imageLabel; + SeExprEditor *_editor; + ImageSynthesizer *_imageSynthesizer; +private slots: + void applyExpression(); +}; diff --git a/src/demos/imageEditor/fbm.se b/src/demos/imageEditor/fbm.se new file mode 100644 index 00000000..912895de --- /dev/null +++ b/src/demos/imageEditor/fbm.se @@ -0,0 +1,17 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + +fbm([10*$u,10*$v,.5]) diff --git a/src/demos/imageEditor/imageEditor.cpp b/src/demos/imageEditor/imageEditor.cpp new file mode 100644 index 00000000..a87e6232 --- /dev/null +++ b/src/demos/imageEditor/imageEditor.cpp @@ -0,0 +1,253 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ + +/** + @file imageEditor.cpp +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ImageEditorDialog.h" + +//-- IMAGE SYNTHESIZER CLASSES AND METHODS --// + +double clamp(double x){return std::max(0.,std::min(255.,x));} + +// Simple image synthesizer expression class to support demo image editor +class ImageSynthExpression:public SeExpression +{ +public: + // Constructor that takes the expression to parse + ImageSynthExpression(const std::string& expr) + :SeExpression(expr) + {} + + // Simple variable that just returns its internal value + struct Var:public SeExprScalarVarRef + { + Var(const double val):val(val){} + Var(){} + double val; // independent variable + void eval(const SeExprVarNode* /*node*/,SeVec3d& result) + {result[0]=val;} + }; + // variable map + mutable std::map vars; + + // resolve function that only supports one external variable 'x' + SeExprVarRef* resolveVar(const std::string& name) const + { + std::map::iterator i=vars.find(name); + if(i != vars.end()) return &i->second; + return 0; + } +}; + +class ImageSynthesizer +{ +public: + ImageSynthesizer(); + unsigned char *evaluateExpression(const std::string &exprStr); +private: + int _width; + int _height; +}; + +ImageSynthesizer::ImageSynthesizer() +{ + _width = 256; + _height = 256; +} + +unsigned char *ImageSynthesizer::evaluateExpression(const std::string &exprStr) +{ + ImageSynthExpression expr(exprStr); + + // make variables + expr.vars["u"]=ImageSynthExpression::Var(0.); + expr.vars["v"]=ImageSynthExpression::Var(0.); + expr.vars["w"]=ImageSynthExpression::Var(_width); + expr.vars["h"]=ImageSynthExpression::Var(_height); + + // check if expression is valid + bool valid=expr.isValid(); + if(!valid){ + std::cerr<<"Invalid expression "<setWindowTitle("Image Synthesis Editor"); + + // Image Previewer + _imageLabel = new QLabel(); + _imageLabel->setFixedSize(256,256); + _imageLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter ); + QImage image("./src/doc/html/seexprlogo.png"); // just a fun default + QPixmap imagePixmap = QPixmap::fromImage(image); + imagePixmap = imagePixmap.scaled(256, 256, Qt::KeepAspectRatio); + _imageLabel->setPixmap(imagePixmap); + + // Expression controls + SeExprEdControlCollection *controls = new SeExprEdControlCollection(); + QScrollArea* scrollArea=new QScrollArea(); + scrollArea->setMinimumHeight(100); + scrollArea->setFixedWidth(450); + scrollArea->setWidgetResizable(true); + scrollArea->setWidget(controls); + + // Expression editor + _editor = new SeExprEditor(this, controls); + + // Expression browser + SeExprEdBrowser *browser = new SeExprEdBrowser(0, _editor); + + // Add user expressions, example expressions to browser list. + browser->addUserExpressionPath("imageEditor"); +#ifdef IMAGE_EDITOR_ROOT + std::string exPathStr = IMAGE_EDITOR_ROOT; + exPathStr += "/expressions"; + browser->addPath("Examples", exPathStr); +#else + browser->addPath("Examples", "./src/demos/imageEditor"); +#endif + browser->update(); + + // Create apply button and connect to image preview. + QPushButton *applyButton=new QPushButton("Apply"); + connect(applyButton, SIGNAL(clicked()), (ImageEditorDialog*)this, SLOT(applyExpression())); + + // Layout widgets: Top section contains left side with previewer and + // controls, right side with browser. Bottom section contains editor + // and apply button. + QVBoxLayout *rootLayout = new QVBoxLayout(); + this->setLayout(rootLayout); + + QWidget* topWidget=new QWidget(); + QHBoxLayout* topLayout=new QHBoxLayout(); + topLayout->setContentsMargins(0,0,0,0); + topWidget->setLayout(topLayout); + + QWidget *leftWidget=new QWidget(); + QVBoxLayout *leftLayout=new QVBoxLayout(); + leftLayout->setContentsMargins(0,0,0,0); + leftWidget->setLayout(leftLayout); + leftLayout->addWidget(_imageLabel); + leftLayout->addWidget(scrollArea,1); + + QWidget *bottomWidget=new QWidget(); + QVBoxLayout *bottomLayout=new QVBoxLayout(); + bottomLayout->setContentsMargins(0,0,0,0); + bottomWidget->setLayout(bottomLayout); + + QWidget *buttonWidget=new QWidget(); + QHBoxLayout *buttonLayout = new QHBoxLayout(0); + buttonWidget->setLayout(buttonLayout); + buttonLayout->addWidget(applyButton); + + topLayout->addWidget(leftWidget); + topLayout->addWidget(browser,1); + + bottomLayout->addWidget(_editor); + bottomLayout->addWidget(buttonWidget); + + rootLayout->addWidget(topWidget); + rootLayout->addWidget(bottomWidget); +} + +// Apply expression, if any, from the editor contents to the preview image +void ImageEditorDialog::applyExpression() +{ + std::string exprStr = _editor->getExpr(); + if( exprStr.empty() ) + { + QMessageBox msgBox; + msgBox.setText("No expression entered in the editor."); + msgBox.exec(); + } else { + QImage image(_imageSynthesizer->evaluateExpression(exprStr), + 256, + 256, + QImage::Format_RGB32); + if( image.isNull() ) + { + QMessageBox msgBox; + msgBox.setText("Error evaluating expression to create preview image."); + msgBox.exec(); + } else { + QPixmap imagePixmap = QPixmap::fromImage(image); + _imageLabel->setPixmap(imagePixmap); + } + } +} + +//-- MAIN --// + +int main(int argc, char *argv[]){ + QApplication app(argc, argv); + ImageEditorDialog *dialog = new ImageEditorDialog(0); + dialog->show(); + app.exec(); + return 0; +} + diff --git a/src/demos/imageEditor/noise.se b/src/demos/imageEditor/noise.se new file mode 100644 index 00000000..23f93198 --- /dev/null +++ b/src/demos/imageEditor/noise.se @@ -0,0 +1,17 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + +noise(10*$u,10*$v) diff --git a/src/demos/imageEditor/noisecolor1.se b/src/demos/imageEditor/noisecolor1.se new file mode 100644 index 00000000..938a5eee --- /dev/null +++ b/src/demos/imageEditor/noisecolor1.se @@ -0,0 +1,23 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + +$val=noise(10*$u,10*$v); +$color=ccurve($val, + 0.000, [1.000, 1.000, 0.498], 4, + 0.590, [0.333, 0.000, 0.000], 4, + 0.665, [1.000, 1.000, 0.000], 4); + +$color diff --git a/src/demos/imageEditor/noisecolor2.se b/src/demos/imageEditor/noisecolor2.se new file mode 100644 index 00000000..03bbd7d6 --- /dev/null +++ b/src/demos/imageEditor/noisecolor2.se @@ -0,0 +1,23 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + +$val=voronoi(5*[$u,$v,.5],4,.6,.2); +$color=ccurve($val, + 0.000, [0.141, 0.059, 0.051], 4, + 0.185, [0.302, 0.176, 0.122], 4, + 0.301, [0.651, 0.447, 0.165], 4, + 0.462, [0.976, 0.976, 0.976], 4); +$color diff --git a/src/demos/imageEditor/raytrace.se b/src/demos/imageEditor/raytrace.se new file mode 100644 index 00000000..656cb25c --- /dev/null +++ b/src/demos/imageEditor/raytrace.se @@ -0,0 +1,46 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + +$Cs=[1.000, 0.000, 1.000]; # Sphere Color +$L1=norm([-1.3,-.3,0]); # Light Direction 1 +$L2=norm([.8,-1,-1]); # Light Direction 2 +$sp=[0.000, 0.000, -3.000]; # Sphere center +$d=norm([$u-.5,$v-.5,-1]); # ray direction +$o=[0.000, 0.000, 0.000]; # ray origin +$r=1.000; # sphere radius +# quadratic coefficients +$a=dot($d,$d); +$ominussp=$o-$sp; +$b=2*dot($d,$ominussp); +$c=dot($ominussp,$ominussp)-$r*$r; +# discriminant +$disc=$b*$b-4*$a*$c; +$color=0.000; +if($disc>0){ # two hit case + # minimum ray parameter + $t=min((-$b+sqrt($disc))/(2*$a),(-$b-sqrt($disc))/(2*$a))[0]; + if($t>=0){ # if we are in front of camera + $Pintersect=$o+$d*$t; # point of intersection + $N=norm($Pintersect-$sp); # intersection normal + # lighting + $H1=(-$L1+-$d)/length($L1+$d); + $color=max(dot($N,-$L1),0)*($Cs*.3+.5*max(0,dot($H1,$N))^80); + $H2=(-$L2+-$d)/length($L2+$d); + $color+=max(dot($N,-$L2),0)*($Cs*.3+.5*max(0,dot($H2,$N))^80); + } +} +# return color +$color diff --git a/src/demos/imageEditor/sinc.se b/src/demos/imageEditor/sinc.se new file mode 100644 index 00000000..7da02417 --- /dev/null +++ b/src/demos/imageEditor/sinc.se @@ -0,0 +1,21 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + +x=u-.5; +y=v-.5; +dist=x*x+y*y; +sin(dist*300)*cnoise(5*[$u,$v,0]) + diff --git a/src/demos/imageSynth/CMakeLists.txt b/src/demos/imageSynth/CMakeLists.txt index dc2a7ce7..85e20919 100644 --- a/src/demos/imageSynth/CMakeLists.txt +++ b/src/demos/imageSynth/CMakeLists.txt @@ -1,35 +1,18 @@ -# SEEXPR SOFTWARE -# Copyright 2011 Disney Enterprises, Inc. All rights reserved -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation -# Studios" or the names of its contributors may NOT be used to -# endorse or promote products derived from this software without -# specific prior written permission from Walt Disney Pictures. -# -# Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -# IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 FIND_PACKAGE(PNG) IF(PNG_FOUND) diff --git a/src/demos/imageSynth/examples/fbm.se b/src/demos/imageSynth/examples/fbm.se index ae95121e..912895de 100644 --- a/src/demos/imageSynth/examples/fbm.se +++ b/src/demos/imageSynth/examples/fbm.se @@ -1 +1,17 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + fbm([10*$u,10*$v,.5]) diff --git a/src/demos/imageSynth/examples/noise.se b/src/demos/imageSynth/examples/noise.se index db2ef8b0..23f93198 100644 --- a/src/demos/imageSynth/examples/noise.se +++ b/src/demos/imageSynth/examples/noise.se @@ -1 +1,17 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + noise(10*$u,10*$v) diff --git a/src/demos/imageSynth/examples/noisecolor1.se b/src/demos/imageSynth/examples/noisecolor1.se index ff470852..938a5eee 100644 --- a/src/demos/imageSynth/examples/noisecolor1.se +++ b/src/demos/imageSynth/examples/noisecolor1.se @@ -1,3 +1,19 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + $val=noise(10*$u,10*$v); $color=ccurve($val, 0.000, [1.000, 1.000, 0.498], 4, diff --git a/src/demos/imageSynth/examples/noisecolor2.se b/src/demos/imageSynth/examples/noisecolor2.se index 7a477a38..03bbd7d6 100644 --- a/src/demos/imageSynth/examples/noisecolor2.se +++ b/src/demos/imageSynth/examples/noisecolor2.se @@ -1,3 +1,19 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + $val=voronoi(5*[$u,$v,.5],4,.6,.2); $color=ccurve($val, 0.000, [0.141, 0.059, 0.051], 4, diff --git a/src/demos/imageSynth/examples/raytrace.se b/src/demos/imageSynth/examples/raytrace.se index 2a9f7bb4..656cb25c 100644 --- a/src/demos/imageSynth/examples/raytrace.se +++ b/src/demos/imageSynth/examples/raytrace.se @@ -1,3 +1,19 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + $Cs=[1.000, 0.000, 1.000]; # Sphere Color $L1=norm([-1.3,-.3,0]); # Light Direction 1 $L2=norm([.8,-1,-1]); # Light Direction 2 diff --git a/src/demos/imageSynth/examples/run.sh b/src/demos/imageSynth/examples/run.sh index 4ff02bf1..3cd15f36 100644 --- a/src/demos/imageSynth/examples/run.sh +++ b/src/demos/imageSynth/examples/run.sh @@ -1,5 +1,20 @@ #!/bin/sh +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + RES=256 for i in *.se; do FNAME=`basename $i .se`.png; diff --git a/src/demos/imageSynth/examples/sinc.se b/src/demos/imageSynth/examples/sinc.se index 2db746a4..7da02417 100644 --- a/src/demos/imageSynth/examples/sinc.se +++ b/src/demos/imageSynth/examples/sinc.se @@ -1,3 +1,19 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + x=u-.5; y=v-.5; dist=x*x+y*y; diff --git a/src/demos/imageSynth/imageSynth.cpp b/src/demos/imageSynth/imageSynth.cpp index 324b9773..2a90b4b9 100644 --- a/src/demos/imageSynth/imageSynth.cpp +++ b/src/demos/imageSynth/imageSynth.cpp @@ -1,41 +1,24 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ /** @file imageSynth.cpp */ #include +#include #include #include #include @@ -146,12 +129,16 @@ int main(int argc,char *argv[]){ png_init_io(png_ptr,fp); int color_type=PNG_COLOR_TYPE_RGBA; png_set_IHDR(png_ptr,info_ptr,width,height,8,color_type,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT); - const unsigned char *ptrs[height]; + // Use vector instead of const array to fix Windows compile error -jb + std::vector ptrs; for(int i=0;i #include diff --git a/src/demos/rman/test.rib b/src/demos/rman/test.rib index 80a37600..ea1e4678 100644 --- a/src/demos/rman/test.rib +++ b/src/demos/rman/test.rib @@ -1,3 +1,19 @@ + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 + ##RenderMan RIB version 3.04 Sides 2 diff --git a/src/demos/rman/testdisp.sl b/src/demos/rman/testdisp.sl index fa61c5dd..0494e553 100644 --- a/src/demos/rman/testdisp.sl +++ b/src/demos/rman/testdisp.sl @@ -1,38 +1,18 @@ - - /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ plugin "libSeExprOp.so"; diff --git a/src/demos/rman/testse.sl b/src/demos/rman/testse.sl index c05caa31..89f5c636 100644 --- a/src/demos/rman/testse.sl +++ b/src/demos/rman/testse.sl @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ plugin "libSeExprOp"; diff --git a/src/demos/segraph/CMakeLists.txt b/src/demos/segraph/CMakeLists.txt index 8dc1daca..af367952 100644 --- a/src/demos/segraph/CMakeLists.txt +++ b/src/demos/segraph/CMakeLists.txt @@ -1,46 +1,31 @@ -# SEEXPR SOFTWARE -# Copyright 2011 Disney Enterprises, Inc. All rights reserved -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation -# Studios" or the names of its contributors may NOT be used to -# endorse or promote products derived from this software without -# specific prior written permission from Walt Disney Pictures. -# -# Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -# IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 find_package(Qt4 COMPONENTS QtCore QtGui) # find and setup Qt4 for this project if(QT4_FOUND) - set(segraph_MOC_HDRS Graph.h GraphWindow.h Functions.h) - set(segraph_CPPS main.cpp Graph.cpp GraphWindow.cpp Functions.cpp) + set(segraph_MOC_HDRS Graph.h GraphWindow.h) + set(segraph_CPPS segraph.cpp Graph.cpp GraphWindow.cpp) qt4_wrap_cpp(segraph_MOC_SRCS ${segraph_MOC_HDRS}) add_executable(segraph ${segraph_CPPS} ${segraph_MOC_SRCS}) install(TARGETS segraph DESTINATION share/SeExpr/demo) - INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}) + include_directories(${QT_INCLUDE_DIR}) + include_directories(${SEEXPR_EDITOR_INCLUDES}) target_link_libraries(segraph ${QT_QTCORE_LIBRARY}) target_link_libraries(segraph ${QT_QTGUI_LIBRARY}) target_link_libraries(segraph ${SEEXPR_LIBRARIES}) + target_link_libraries(segraph ${SEEXPR_EDITOR_LIBRARIES}) endif(QT4_FOUND) diff --git a/src/demos/segraph/Functions.cpp b/src/demos/segraph/Functions.cpp deleted file mode 100644 index 63694d1c..00000000 --- a/src/demos/segraph/Functions.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -*/ -#include "Functions.h" - - -//! Simple expression class to support our function grapher -class GrapherExpr:public SeExpression -{ - const std::map& vars; -public: - //! Constructor that takes the expression to parse - GrapherExpr(const std::string& expr,const std::map& vars) - :SeExpression(expr),vars(vars) - {} - - //! set the independent variable - void setX(double x_input) - {x.val=x_input;} - -private: - //! independent variable - mutable SimpleVar x; - - //! resolve function that only supports one external variable 'x' - SeExprVarRef* resolveVar(const std::string& name) const - { - // check my internal variable - if(name == "x") return &x; - // check external variable table - std::map::const_iterator i=vars.find(name); - if(i!=vars.end()) return const_cast(&i->second); - // nothing found - return 0; - } -}; - -void Functions:: -setVar(const std::string& name,const double val) -{ - variables[name].val=val; -} - -Functions:: -Functions() -{ - variables["t"].val=0.; -} - -Functions:: -~Functions() -{ - for(size_t i=0;iisValid()){ - std::cerr<<"parse error on '"<parseError()<setX(x); - SeVec3d val=functions[functionId]->evaluate(); - //std::cerr<<"evaluating x="<=functions.size()) return false; - return selected[functionId]; -} - -//! Sets if the given functionId is selected -void Functions:: -setSelected(unsigned int functionId,bool val) -{ - if(functionId& selectedFunctions) const -{ - for(size_t i=0;i -#include -#include - -#include - -//! Simple variable that just returns its internal value -struct SimpleVar:public SeExprScalarVarRef -{ - double val; // independent variable - void eval(const SeExprVarNode* /*node*/,SeVec3d& result) - {result[0]=val;} -}; - -//! Model representing all the functions that the grapher handles -class GrapherExpr; -class Functions:public QAbstractTableModel -{ - Q_OBJECT; - - //! List of expression classes - std::vector functions; - //! Expression strings - std::vector strings; - //! Whether item is selected - std::vector selected; - //! Extra variables - std::map variables; - -public: - Functions(); - ~Functions(); - //! Sets up a function for evaluation - void setupFunction(const std::string& s,GrapherExpr** exprDest); - //! Adds a function given a qstring - void addFunction(const QString& s); - //! Evaluates functionId given at independent variable x - bool isValid(int functionId) const; - //! Evaluates functionId given at independent variable x - double eval(int functionId,double x) const; - //! Returns true if the given functionId is selected - bool isSelected(unsigned int functionId) const; - //! Sets if the given functionId is selected - void setSelected(unsigned int functionId,bool val); - //! Gets a list of all selection functions - void getSelected(std::vector& selectedFunctions) const; - //! Set the time - void setVar(const std::string& name,const double val); - - - /************************************************** - * Items below implement the QAbstractItemModel - *************************************************/ - int rowCount(const QModelIndex&) const; - int columnCount(const QModelIndex&) const; - QColor getColor(const int row) const; - QVariant data(const QModelIndex& index,int role) const; - QVariant headerData(int column,Qt::Orientation orient,int role) const; - bool setData(const QModelIndex& index,const QVariant& value,int role); - Qt::ItemFlags flags(const QModelIndex& index) const; - -}; - -#endif diff --git a/src/demos/segraph/Graph.cpp b/src/demos/segraph/Graph.cpp index 350a8f9f..dcb1e043 100644 --- a/src/demos/segraph/Graph.cpp +++ b/src/demos/segraph/Graph.cpp @@ -1,54 +1,34 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #include "Graph.h" +#include "SeExprMacros.h" #ifndef SEEXPR_WIN32 # include #endif #include -Graph:: -Graph(Functions* functions,QStatusBar* status) - :funcs(*functions),operationCode(NONE),rootShow(false),minShow(false),dragging(false),scaling(false), - status(status) +Graph::Graph(QStatusBar* status,std::vector& exprs) + :exprs(exprs),operationCode(NONE),rootShow(false),minShow(false), + dragging(false),scaling(false),status(status) { // use standard window... xmin=-10;xmax=10; ymin=-10;ymax=10; // use base 2 log for hash marks and grid logBase=2.; - funcs.addFunction("xmod=x-2*PI*t;sin(xmod)"); - funcs.addFunction("xmod=x-2*PI*t;xmod-xmod*xmod*xmod/6"); } float Graph:: @@ -108,7 +88,7 @@ paintEvent(QPaintEvent */*event*/) float powerx=(int)floor(log(xmax-xmin)/log(logBase)); float powery=(int)floor(log(ymax-ymin)/log(logBase)); - int powerOffsetSmall=5; + int powerOffsetSmall=4; int powerOffsetBig=1; drawX(painter,powerx-powerOffsetSmall); drawY(painter,powery-powerOffsetSmall); @@ -142,8 +122,12 @@ paintEvent(QPaintEvent */*event*/) painter.setRenderHints(QPainter::Antialiasing); - for(int i=0;iy_per_pixel*100 && xrate>.1*x_per_pixel){xrate/=2;continue;} if(fabs(y-yold) #include #include -#include "Functions.h" #include +#include +#include "GrapherExpr.h" static const int divs=1; @@ -52,7 +35,7 @@ class Graph:public QWidget enum OperationCode{NONE=0,FIND_MIN,FIND_MAX,FIND_ROOT}; private: - Functions& funcs; + std::vector& exprs; float logBase; //! operation code type @@ -79,7 +62,7 @@ class Graph:public QWidget QStatusBar* status; public: - Graph(Functions* functions,QStatusBar* status); + Graph(QStatusBar* status,std::vector& exprs); protected: //! Window in graph space float xmin,xmax,ymin,ymax; @@ -91,8 +74,8 @@ class Graph:public QWidget void drawY(QPainter& painter,int power,bool label=false); //! Draw graph void paintEvent(QPaintEvent * /*event*/); - //! Plot a single function - void plot(QPainter& painter,int funcId); + //! Plot a single function (new version) + void plotNew(QPainter& painter,int funcId); void mousePressEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event); diff --git a/src/demos/segraph/GraphWindow.cpp b/src/demos/segraph/GraphWindow.cpp index 7f9b56c3..c27efb1c 100644 --- a/src/demos/segraph/GraphWindow.cpp +++ b/src/demos/segraph/GraphWindow.cpp @@ -1,45 +1,30 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #include "GraphWindow.h" #include #include +#include GraphWindow:: GraphWindow(QWidget* parent) - :QFrame(parent),time(0) + :QFrame(parent),time(0),animating(false) { + variables["t"].val=0.; + //######################################### // Layout framework //######################################### @@ -51,33 +36,51 @@ GraphWindow(QWidget* parent) status=new QStatusBar(); mainvbox->addWidget(status); - // Function model - functions=new Functions(); //######################################### // Make our graph //######################################### - graph=new Graph(functions,status); - graph->setMinimumWidth(320); - graph->setMinimumHeight(320); + graph=new Graph(status,_exprs); + graph->setMinimumWidth(640); + graph->setMinimumHeight(480); layout->addWidget(graph,2); //######################################### // Make button bar and function list //######################################### QVBoxLayout* rightLayout=new QVBoxLayout(); + layout->addLayout(rightLayout,1); // Make an entry for new functions - edit=new QLineEdit(); - rightLayout->addWidget(new QLabel("f(x)="),0); - rightLayout->addWidget(edit,0); + + rightLayout->setMargin(0); + for(int i=0;i<5;i++){ + SeExprEdShortEdit* shortEdit=new SeExprEdShortEdit(0); + shortEdit->setMinimumWidth(512); + rightLayout->addWidget(shortEdit); + QObject::connect(shortEdit,SIGNAL(exprChanged()),this,SLOT(exprsEdited())); + _edits.push_back(shortEdit); + _exprs.push_back(new GrapherExpr("",variables)); + } + + // set default exprs + + _edits[0]->setExpressionString("a=0.34483; #-10.0,10.0\nb=0.41379; #-10.0,10.0\nc=-0.34482; #-10.0,10.0\na*x^2+b*x+c"); + + _exprs[1]->setExpr("frequency=8.32724; # 0.1, 10.0\ +amp = -4; # 0.0, 10.0\ +fbm(frequency*x)*amp\ +"); + + _exprs[2]->setExpr("""frequency=8.32724; # 0.1, 10.0\ +amp = 1; # 0.0, 10.0\ +sin(frequency*x)*amp-5\ +"); + + rightLayout->addStretch(1); // make a table view that is driven by functions - table=new QTableView; - table->setModel(functions); - table->resizeColumnToContents(0); - rightLayout->addWidget(table,2); // Make buttons for computing roots rootbutton=new QPushButton("Find Root"); @@ -98,13 +101,7 @@ GraphWindow(QWidget* parent) connect(maxbutton,SIGNAL(clicked()),SLOT(findRootOrExtrema())); // Connect edit box to add new function - connect(edit,SIGNAL(editingFinished()),SLOT(addNewFunction())); // If data,selection,or layout changes in model then redraw graph - connect(functions,SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)),graph,SLOT(redraw())); - connect(functions,SIGNAL(layoutChanged()),graph,SLOT(redraw())); - connect(table->selectionModel(),SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)), - SLOT(selectionChanged(const QItemSelection&,const QItemSelection&))); - QTimer::singleShot(1,this,SLOT(updateTime())); } @@ -112,18 +109,7 @@ GraphWindow(QWidget* parent) GraphWindow:: ~GraphWindow() { - delete functions; -} - -void GraphWindow:: -addNewFunction() -{ - QString text=edit->text(); - if(text!=QString("")) - functions->addFunction(text); - edit->setText(""); - status->showMessage(""); - table->repaint(); + for(unsigned int i=0;i<_exprs.size();i++) delete _exprs[i]; } void GraphWindow:: @@ -136,7 +122,6 @@ findRootOrExtrema() else if(sender==maxbutton) code=Graph::FIND_MAX; std::vector selected; - functions->getSelected(selected); if(selected.size() != 1){ status->showMessage("You need to select exactly 1 function"); }else{ @@ -147,28 +132,25 @@ findRootOrExtrema() } void GraphWindow:: -selectionChanged(const QItemSelection& selected,const QItemSelection& unselected) +updateTime() { - status->showMessage(""); - QModelIndexList removeList=unselected.indexes(); - for(int i=0;isetSelected(removeList[i].row(),false); - } - QModelIndexList addList=selected.indexes(); - for(int i=0;isetSelected(addList[i].row(),true); + if(animating){ + time+=1./24; + if(time>1) time=0; + timeSlider->setValue(time*24); + variables["t"].val=time; + graph->repaint(); } - - graph->repaint(); + QTimer::singleShot(50.,this,SLOT(updateTime())); } void GraphWindow:: -updateTime() +exprsEdited() { - time+=1./24; - if(time>1) time=0; - functions->setVar("t",time); - timeSlider->setValue(time*24); + for(size_t i=0;i<_edits.size();i++){ + SeExprEdShortEdit& edit=*_edits[i]; + _exprs[i]->setExpr(edit.getExpressionString()); + _exprs[i]->isValid(); + } graph->repaint(); - QTimer::singleShot(50.,this,SLOT(updateTime())); } diff --git a/src/demos/segraph/GraphWindow.h b/src/demos/segraph/GraphWindow.h index f0137248..5965c636 100644 --- a/src/demos/segraph/GraphWindow.h +++ b/src/demos/segraph/GraphWindow.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef _GraphWindow_h_ #define _GraphWindow_h_ @@ -46,34 +28,36 @@ #include #include -#include "Functions.h" #include "Graph.h" +#include "GrapherExpr.h" + +class SeExprEdShortEdit; + //! Main window that contains graph widget and function list class GraphWindow:public QFrame { Q_OBJECT; public: Graph* graph; - QLineEdit* edit; - Functions* functions; - QTableView* table; QPushButton *rootbutton,*minbutton,*maxbutton; QSlider *timeSlider; QStatusBar* status; GraphWindow(QWidget* parent=0); ~GraphWindow(); private slots: - //! Add new function when it is entered into the add box - void addNewFunction(); //! Start finding a numeric quantity after button clicked void findRootOrExtrema(); - //! Update the selection in the internal model - void selectionChanged(const QItemSelection& selected,const QItemSelection& unselected); //! Update time void updateTime(); + //! Exprs edits + void exprsEdited(); private: float time; + bool animating; + std::vector _edits; + std::vector _exprs; + std::map variables; }; #endif diff --git a/src/demos/segraph/GrapherExpr.h b/src/demos/segraph/GrapherExpr.h new file mode 100644 index 00000000..7ca46a12 --- /dev/null +++ b/src/demos/segraph/GrapherExpr.h @@ -0,0 +1,60 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#ifndef _GrapherExpr_ +#define _GrapherExpr_ +#include + +//! Simple variable that just returns its internal value +struct SimpleVar:public SeExprScalarVarRef +{ + double val; // independent variable + void eval(const SeExprVarNode* /*node*/,SeVec3d& result) + {result[0]=val;} +}; + + +//! Simple expression class to support our function grapher +class GrapherExpr:public SeExpression +{ + const std::map& vars; +public: + //! Constructor that takes the expression to parse + GrapherExpr(const std::string& expr,const std::map& vars) + :SeExpression(expr),vars(vars) + {} + + //! set the independent variable + void setX(double x_input) + {x.val=x_input;} + +private: + //! independent variable + mutable SimpleVar x; + + //! resolve function that only supports one external variable 'x' + SeExprVarRef* resolveVar(const std::string& name) const + { + // check my internal variable + if(name == "x") return &x; + // check external variable table + std::map::const_iterator i=vars.find(name); + if(i!=vars.end()) return const_cast(&i->second); + // nothing found + return 0; + } +}; +#endif diff --git a/src/demos/segraph/main.cpp b/src/demos/segraph/main.cpp deleted file mode 100644 index 612652d7..00000000 --- a/src/demos/segraph/main.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -*/ -#include -#include "GraphWindow.h" -#include -#include -#include - -int main(int argc,char *argv[]) -{ - QApplication app(argc,argv); - GraphWindow* graph=new GraphWindow; - graph->show(); - app.exec(); - - return 0; -} diff --git a/src/demos/segraph/segraph.cpp b/src/demos/segraph/segraph.cpp new file mode 100644 index 00000000..2b2a4552 --- /dev/null +++ b/src/demos/segraph/segraph.cpp @@ -0,0 +1,31 @@ +/* +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +*/ +#include +#include "GraphWindow.h" +#include +#include +#include + +int main(int argc,char *argv[]) +{ + QApplication app(argc,argv); + GraphWindow* graph=new GraphWindow; + graph->show(); + app.exec(); + + return 0; +} diff --git a/src/doc/CMakeLists.txt b/src/doc/CMakeLists.txt index 2e0901be..f4b376bf 100644 --- a/src/doc/CMakeLists.txt +++ b/src/doc/CMakeLists.txt @@ -1,35 +1,18 @@ -# PARTIO SOFTWARE -# Copyright 2011 Disney Enterprises, Inc. All rights reserved -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation -# Studios" or the names of its contributors may NOT be used to -# endorse or promote products derived from this software without -# specific prior written permission from Walt Disney Pictures. -# -# Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -# IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 find_package(Doxygen) IF(DOXYGEN_FOUND AND NOT WIN32) @@ -44,4 +27,6 @@ IF(DOXYGEN_FOUND AND NOT WIN32) INSTALL( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ DESTINATION share/doc/SeExpr ) INSTALL( FILES userdoc.txt DESTINATION share/doc/SeExpr/ RENAME SeExpressions.html ) INSTALL( FILES Se_voronoi_1.png Se_voronoi_2.png Se_voronoi_3.png Se_voronoi_4.png Se_voronoi_5.png DESTINATION share/doc/SeExpr ) + INSTALL( FILES ui_addWidget.png ui_browser.png ui_editor1.png ui_emptyLayout.png ui_final.png ui_preview.png DESTINATION share/doc/SeExpr ) + ENDIF(DOXYGEN_FOUND AND NOT WIN32) diff --git a/src/doc/Doxyfile.in b/src/doc/Doxyfile.in index 3e355ea6..727a5b28 100644 --- a/src/doc/Doxyfile.in +++ b/src/doc/Doxyfile.in @@ -1,35 +1,17 @@ -# SEEXPR SOFTWARE -# Copyright 2011 Disney Enterprises, Inc. All rights reserved -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation -# Studios" or the names of its contributors may NOT be used to -# endorse or promote products derived from this software without -# specific prior written permission from Walt Disney Pictures. -# -# Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -# IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 # Doxyfile 1.4.7 @@ -493,9 +475,13 @@ WARN_LOGFILE = # with spaces. INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../SeExpr \ - @CMAKE_CURRENT_SOURCE_DIR@/../demos/asciiGraph.cpp \ - @CMAKE_CURRENT_SOURCE_DIR@/../demos/imageSynth/imageSynth.cpp \ - @CMAKE_CURRENT_SOURCE_DIR@ + @CMAKE_CURRENT_SOURCE_DIR@/../SeExprEditor \ + @CMAKE_CURRENT_SOURCE_DIR@/../demos \ + @CMAKE_CURRENT_SOURCE_DIR@/../demos/imageEditor \ + @CMAKE_CURRENT_SOURCE_DIR@/../demos/imageSynth \ + @CMAKE_CURRENT_SOURCE_DIR@/../demos/rman \ + @CMAKE_CURRENT_SOURCE_DIR@/../demos/segraph \ + @CMAKE_CURRENT_SOURCE_DIR@ # If the value of the INPUT tag contains directories, you can use the @@ -517,7 +503,8 @@ RECURSIVE = NO # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +EXCLUDE = @CMAKE_CURRENT_SOURCE_DIR@/../doc/uitutorial.txt \ + @CMAKE_CURRENT_SOURCE_DIR@/../doc/plugins.txt # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded @@ -533,6 +520,11 @@ EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = +# Exclude demo classes from official class documentation. Files are +# still listed in the Files tab. + +EXCLUDE_SYMBOLS = ImageEditorDialog ImageSynth* CalculatorExpr GrapherExpr SeRman* AttrVar Graph* immutable_hash_map SimpleVar + # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). @@ -710,6 +702,12 @@ HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the HTML output directory. + +HTML_EXTRA_FILES = + + # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) diff --git a/src/doc/license.txt b/src/doc/license.txt index 8755a57b..e04cdc9a 100644 --- a/src/doc/license.txt +++ b/src/doc/license.txt @@ -1,34 +1,16 @@
- SEEXPR SOFTWARE
- Copyright 2011 Disney Enterprises, Inc. All rights reserved
- 
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- 
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- 
- * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
- Studios" or the names of its contributors may NOT be used to
- endorse or promote products derived from this software without
- specific prior written permission from Walt Disney Pictures.
- 
- Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
- FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
- IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+Copyright Disney Enterprises, Inc.  All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License
+and the following modification to it: Section 6 Trademarks.
+deleted and replaced with:
+
+6. Trademarks. This License does not grant permission to use the
+trade names, trademarks, service marks, or product names of the
+Licensor and its affiliates, except as required for reproducing
+the content of the NOTICE file.
+
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
 
diff --git a/src/doc/main.txt b/src/doc/main.txt index 139a0451..398757e0 100644 --- a/src/doc/main.txt +++ b/src/doc/main.txt @@ -1,13 +1,31 @@ -/*! \mainpage SeExpr +/*! + * \cond + * Copyright Disney Enterprises, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License + * and the following modification to it: Section 6 Trademarks. + * deleted and replaced with: + * + * 6. Trademarks. This License does not grant permission to use the + * trade names, trademarks, service marks, or product names of the + * Licensor and its affiliates, except as required for reproducing + * the content of the NOTICE file. + * + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * \endcond + * \mainpage SeExpr * \image html seexprlogo.png * \section maindoc User and Programmer Tutorials * - \subpage userdoc - User Documentation * - \subpage plugins - Custom Function Plugins - * \section demos Demo Appliactions + * \section demos Demo Applications * - \subpage mytut (code at asciiGraph.cpp) - * - Image Synthesizer (at imageSynth.cpp) - * - SeGrapher Qt Grapher (at demos/segraph) - * - Renderman Shadeop (at demos/rman) + * - \subpage uitut (code starting at imageEditor.cpp) + * - Image Synthesizer (code at imageSynth.cpp) + * - SeGrapher Qt Grapher (code starting at segraph.cpp) + * - Renderman Shadeop (code at seop.cpp) * \section mainapi Main API pages * - SeExpression - Main class to parse a single expression * - SeExprVarRef - Binding of an external variable to an expression context. @@ -32,6 +50,10 @@ \htmlinclude tutorial.txt */ /** +\page uitut Simple Image Editor UI Tutorial +\htmlinclude uitutorial.txt +*/ +/** \page userdoc User Documentation \htmlinclude userdoc.txt */ diff --git a/src/doc/plugins.txt b/src/doc/plugins.txt index 37adabc8..2c2047b2 100644 --- a/src/doc/plugins.txt +++ b/src/doc/plugins.txt @@ -1,4 +1,21 @@ + + +

Programmer Tutorial

diff --git a/src/doc/ui_addWidget.png b/src/doc/ui_addWidget.png new file mode 100644 index 00000000..960f23ac Binary files /dev/null and b/src/doc/ui_addWidget.png differ diff --git a/src/doc/ui_browser.png b/src/doc/ui_browser.png new file mode 100644 index 00000000..bbfc3714 Binary files /dev/null and b/src/doc/ui_browser.png differ diff --git a/src/doc/ui_editor1.png b/src/doc/ui_editor1.png new file mode 100644 index 00000000..433b6b25 Binary files /dev/null and b/src/doc/ui_editor1.png differ diff --git a/src/doc/ui_emptyLayout.png b/src/doc/ui_emptyLayout.png new file mode 100644 index 00000000..8df78391 Binary files /dev/null and b/src/doc/ui_emptyLayout.png differ diff --git a/src/doc/ui_final.png b/src/doc/ui_final.png new file mode 100644 index 00000000..c3e0f519 Binary files /dev/null and b/src/doc/ui_final.png differ diff --git a/src/doc/ui_preview.png b/src/doc/ui_preview.png new file mode 100644 index 00000000..6a5f4ddf Binary files /dev/null and b/src/doc/ui_preview.png differ diff --git a/src/doc/uitutorial.txt b/src/doc/uitutorial.txt new file mode 100644 index 00000000..18a5ccd9 --- /dev/null +++ b/src/doc/uitutorial.txt @@ -0,0 +1,445 @@ + + +

User Interface Tutorial

+The user interface components included in the SeExpr distribution provide a useful way to visualize the results of your expression evaluations and speed up the process of building expressions. This tutorial uses some of the main UI components to build a simple app for editing and previewing expressions for image synthesis. + +

+The finished example code can be found in ImageEditorDialog Class Reference. + +

+See Simple ASCII Grapher Tutorial for getting started using SeExpr. + +

Problem Overview: Image Synthesis

+ +We'd like to be able to use a GUI expression editor to preview resulting images as we are building our expressions. For example, the evaluation of this: + +
+$val=voronoi(5*[$u,$v,.5],4,.6,.2);
+$color=ccurve($val,
+    0.000, [0.141, 0.059, 0.051], 4, 
+    0.185, [0.302, 0.176, 0.122], 4, 
+    0.301, [0.651, 0.447, 0.165], 4,  
+    0.462, [0.976, 0.976, 0.976], 4);
+$color
+
+ +looks like this:

+ +

+In this tutorial, we are going to write an interface for doing image synthesis using expressions. This example uses the Qt Toolkit and SeExpr libraries. See referenced documentation for more detail. + +

+The components of the interface will include: + +

    +
  • an expression editor
  • +
  • a panel for control widgets
  • +
  • an expression library browser
  • +
  • an image previewer
  • +
+ +

Main Dialog

+ +We will first create a new ImageEditorDialog class based on the QDialog class: + +
+#include <QtGui/QDialog>
+
+class ImageEditorDialog: public QDialog
+{
+public:
+    ImageEditorDialog(QWidget *parent=0);
+};
+
+ImageEditorDialog::ImageEditorDialog(QWidget *parent)
+    :QDialog(parent)
+{
+    this->setWindowTitle("Image Synthesis Editor");
+}
+
+ +A simple main application will show the dialog: + +
+#include <QtGui/QApplication>
+#include "ImageEditorDialog.h"
+
+int main(int argc, char *argv[]){
+    QApplication app(argc, argv);
+    ImageEditorDialog *dialog = new ImageEditorDialog(0);
+    dialog->show();
+    app.exec();
+    return 0;
+}
+
+ +

Widget Controls and Text Editor

+ +Now let's add some controls and an expression editor. The SeExprEdControlCollection class provides the ability to add UI controls (sliders, ramps, etc.) for various types of variables (int, float, color, curves, etc.). The SeExprEditor class provides the ability to manually edit the expression script. +

+We will include two new header files, in addition to the needed Qt header files: + +

+#include <QtGui/QVBoxLayout>
+#include <QtGui/QScrollArea>
+#include <SeExprEdControlCollection.h>
+#include <SeExprEditor.h>
+
+ +and add a private member to the ImageEditorDialog class definition for the editor (we will use the editor's contents later to generate the preview image): + +
+private:
+    SeExprEditor *_editor;
+
+ +Next we'll add 2 new components in the constructor and lay them out. The QScrollArea has specific parameters to properly display the controls. The SeExprEditor constructor takes a pointer to the SeExprEdControlCollection object, so it can connect signals between them: + +
+    // Expression controls
+    SeExprEdControlCollection *controls = new SeExprEdControlCollection();
+    QScrollArea* scrollArea=new QScrollArea();
+    scrollArea->setMinimumHeight(100);
+    scrollArea->setFixedWidth(450);
+    scrollArea->setWidgetResizable(true);
+    scrollArea->setWidget(controls);
+
+    // Expression editor
+    _editor = new SeExprEditor(this, controls);
+
+    // Layout widgets
+    QVBoxLayout *rootLayout = new QVBoxLayout();
+    this->setLayout(rootLayout);
+    rootLayout->addWidget(scrollArea);
+    rootLayout->addWidget(_editor);
+
+ +Already we can use the demo app to create some expressions. + +

+Clicking the Add Widget button will give us a dialog to choose different variable types, with the corresponding expression output displayed in the editor:

+ +

+For example, adding a color widget creates 3 sliders for RGB values which we can edit either from the control sliders or from the text editor:

+ +

Expression Library Browser

+ +

+Next let's add an expression library browser so we can look at example expressions and add our own. We will use the SeExprEdBrowser class and connect it to the editor. + +

+First, we will need an additional header: + +

+#include <SeExprEdBrowser.h>
+
+ +The browser reads from a config.txt file to locate expression files. An example can be found in ./build/src/demos/imageEditor/config.txt. We will create the browser in the ImageEditorDialog constructor: +
+    // Expression browser
+    SeExprEdBrowser *browser = new SeExprEdBrowser(0, _editor);
+
+    // Add user expressions, example expressions to browser list.
+    browser->addUserExpressionPath("imageEditor");
+#ifdef IMAGE_EDITOR_ROOT
+    std::string exPathStr = IMAGE_EDITOR_ROOT;
+    exPathStr += "/expressions";
+    browser->addPath("Examples", exPathStr);
+#else
+    browser->addPath("Examples", "./src/demos/imageEditor");
+#endif
+    browser->update();
+
+ +and adjust the layout to make room for it: + +
+    // Layout widgets: top section containing left and right, and bottom section
+    QVBoxLayout *rootLayout = new QVBoxLayout();
+    this->setLayout(rootLayout);
+
+    QWidget* topWidget=new QWidget();
+    QHBoxLayout* topLayout=new QHBoxLayout();
+    topLayout->setContentsMargins(0,0,0,0);
+    topWidget->setLayout(topLayout);
+
+    QWidget *leftWidget=new QWidget();
+    QVBoxLayout *leftLayout=new QVBoxLayout();
+    leftLayout->setContentsMargins(0,0,0,0);
+    leftWidget->setLayout(leftLayout);
+    leftLayout->addWidget(scrollArea,1);
+
+    QWidget *bottomWidget=new QWidget();
+    QVBoxLayout *bottomLayout=new QVBoxLayout();
+    bottomLayout->setContentsMargins(0,0,0,0);
+    bottomWidget->setLayout(bottomLayout);
+
+    topLayout->addWidget(leftWidget);
+    topLayout->addWidget(browser,1);
+
+    bottomLayout->addWidget(_editor);
+
+    rootLayout->addWidget(topWidget);
+    rootLayout->addWidget(bottomWidget);
+
+ +We now have the ability to browse expression files. Selecting a file from the browser list will load its contents into the editor and create any associated widgets:

+ +

Image Previewer

+ +

+The last component is the image previewer. This borrows heavily from the imageSynth demo code. + +

+We will use a QLabel with a pixmap image generated by some of the code from the imageSynth program. + +

+First some additional headers: + +

+#include <string>
+#include <QtGui/QLabel>
+#include <QtGui/QImage>
+#include <QtGui/QMessageBox>
+
+ +and another new data member in the ImageEditorDialog class for the image label: + +
+private:
+    QLabel *_imageLabel;
+
+ +We'll create the image label in the constructor and add it to the top left of the layout, above the controls (scrollArea): + +
+    // Image Previewer
+    _imageLabel = new QLabel();
+    _imageLabel->setFixedSize(256,256);
+    _imageLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter );
+    QImage image("./src/doc/html/seexprlogo.png"); // just a fun default
+    QPixmap imagePixmap = QPixmap::fromImage(image);
+    imagePixmap = imagePixmap.scaled(256, 256, Qt::KeepAspectRatio);
+    _imageLabel->setPixmap(imagePixmap);
+
+    leftLayout->addWidget(_imageLabel);
+    leftLayout->addWidget(scrollArea,1);
+
+ +The layout should nowlook something like this:

+ +

+To generate an image preview, we will want to evaluate the contents of the editor. We'll need to add an apply button that will evaluate the expression. + +

+First, let's create some classes to handle the image synthesis. This code is a subset of the imageSynth demo code mentioned earlier. The differences are that the pixel order is slightly different for generating a QImage than for generating a PNG file, and the evaluateExpression() method returns a pointer to the image rather than writing the image to file. + +

+#include <png.h>
+#include <SeExpression.h>
+
+double clamp(double x){return std::max(0.,std::min(255.,x));}
+
+// Simple image synthesizer expression class to support demo image editor
+class ImageSynthExpression:public SeExpression
+{
+public:
+    // Constructor that takes the expression to parse
+    ImageSynthExpression(const std::string& expr)
+        :SeExpression(expr)
+    {}
+
+    // Simple variable that just returns its internal value
+    struct Var:public SeExprScalarVarRef
+    {
+        Var(const double val):val(val){}
+        Var(){}
+        double val; // independent variable
+        void eval(const SeExprVarNode* /*node*/,SeVec3d& result)
+        {result[0]=val;}
+    };
+    // variable map
+    mutable std::map<std::string,Var> vars;
+
+    // resolve function that only supports one external variable 'x'
+    SeExprVarRef* resolveVar(const std::string& name) const
+    {
+        std::map<std::string,Var>:iterator i=vars.find(name);
+        if(i != vars.end()) return &i->second;
+        return 0;
+    }
+};
+
+class ImageSynthesizer
+{
+public:
+    ImageSynthesizer();
+    unsigned char *evaluateExpression(const std::string &exprStr);
+private:
+    int _width;
+    int _height;
+};
+
+ImageSynthesizer::ImageSynthesizer()
+{
+    _width = 256;
+    _height = 256;
+}
+
+unsigned char *ImageSynthesizer::evaluateExpression(const std::string &exprStr)
+{
+    ImageSynthExpression expr(exprStr);
+
+    // make variables
+    expr.vars["u"]=ImageSynthExpression::Var(0.);
+    expr.vars["v"]=ImageSynthExpression::Var(0.);
+    expr.vars["w"]=ImageSynthExpression::Var(_width);
+    expr.vars["h"]=ImageSynthExpression::Var(_height);
+
+    // check if expression is valid
+    bool valid=expr.isValid();
+    if(!valid){
+        std::cerr<<"Invalid expression "<<std::endl;
+        std::cerr<<expr.parseError()<<std::endl;
+        return NULL;
+    }
+
+    // evaluate expression
+    std::cerr<<"Evaluating expression..."<<std::endl;
+    unsigned char* image=new unsigned char[_width*_height*4];
+    double one_over_width=1./_width,one_over_height=1./_height;
+    double& u=expr.vars["u"].val;
+    double& v=expr.vars["v"].val;
+    unsigned char* pixel=image;
+    for(int row=0;row<_height;row++){
+        for(int col=0;col<_width;col++){
+            u=one_over_width*(col+.5);
+            v=one_over_height*(row+.5);
+            SeVec3d result=expr.evaluate();
+            pixel[0]=clamp(result[0]*256.);
+            pixel[1]=clamp(result[1]*256.);
+            pixel[2]=clamp(result[2]*256.);
+            pixel[3]=255;
+            pixel+=4;
+        }
+    }
+
+    return image;
+}
+
+ +Now we're ready to create an apply button and add it to the bottom of the layout: + +
+#include <QtGui/QPushButton>
+#include <QtGui/QMessageBox>
+
+    // Create apply button and connect to image preview.
+    QPushButton *applyButton=new QPushButton("Apply");
+    connect(applyButton, SIGNAL(clicked()), (ImageEditorDialog*)this, SLOT(applyExpression()));
+
+    QWidget *buttonWidget=new QWidget();
+    QHBoxLayout *buttonLayout = new QHBoxLayout(0);
+    buttonWidget->setLayout(buttonLayout);
+    buttonLayout->addWidget(applyButton);
+
+    bottomLayout->addWidget(_editor);
+    bottomLayout->addWidget(buttonWidget);
+
+ +We will need to write the applyExpression() function to call the ImageSynthesizer object to evaluate the expression inside the editor. First, we need to include the Q_OBJECT macro in the ImageEditorDialog class definition, since we're going to be connecting signals and slots: + +
+class ImageEditorDialog: public QDialog
+{
+    Q_OBJECT
+    ...
+
+ +Next, we'll add a new data member for the ImageSynthesizer instance as well as the applyExpression() function to the ImageEditorDialog class definition: + +
+private:
+    ImageSynthesizer *_imageSynthesizer;
+private slots:
+    void applyExpression();
+
+ +and, initialize _imageSynthesizer in the constructor: + +
+    _imageSynthesizer = new ImageSynthesizer();
+
+ +Now we can write the function to evaluate the expression and generate a preview image: + +
+// Apply expression, if any, from the editor contents to the preview image
+void ImageEditorDialog::applyExpression()
+{
+    std::string exprStr = _editor->getExpr();
+    if( exprStr.empty() )
+    {
+        QMessageBox msgBox;
+        msgBox.setText("No expression entered in the editor.");
+        msgBox.exec();
+    } else {
+        QImage image(_imageSynthesizer->evaluateExpression(exprStr),
+                     256,
+                     256,
+                     QImage::Format_RGB32);
+        if( image.isNull() )
+        {
+            QMessageBox msgBox;
+            msgBox.setText("Error evaluating expression to create preview image.");
+            msgBox.exec();
+        } else {
+            QPixmap imagePixmap = QPixmap::fromImage(image);
+            _imageLabel->setPixmap(imagePixmap);
+        }
+    }
+}
+
+ +Finally, we'll have to pull out the ImageEditorDialog class definition into its own header, ImageEditorDialog.h, so the Qt MOC files will build correctly: + +
+#include <QtGui/QDialog>
+
+class QLabel;
+class SeExprEditor;
+class ImageSynthesizer;
+
+class ImageEditorDialog: public QDialog
+{
+    Q_OBJECT
+public:
+    ImageEditorDialog(QWidget *parent=0);
+private:
+    QLabel *_imageLabel;
+    SeExprEditor *_editor;
+    ImageSynthesizer *_imageSynthesizer;
+private slots:
+    void applyExpression();
+};
+
+ +Now we can load expressions from a library, create new expressions manually as well as by creating new controls, and see all our changes in an image preview as we go:

+ +

+A next simple step would be to add a Save button to save expressions from the editor to your own ~/imageEditor/expressions directory. The library browser will pick these up automatically, based on the context (imageEditor) and the hard-coded directory (expressions). This exercise is left to the reader to implement. diff --git a/src/doc/userdoc.txt b/src/doc/userdoc.txt index 378fb334..f49e5913 100644 --- a/src/doc/userdoc.txt +++ b/src/doc/userdoc.txt @@ -1,3 +1,20 @@ + +

Shader/XGen/Paint3d Expressions

  • Variables
  • diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index b2f8b100..351bd51d 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,35 +1,18 @@ -# SEEXPR SOFTWARE -# Copyright 2011 Disney Enterprises, Inc. All rights reserved -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation -# Studios" or the names of its contributors may NOT be used to -# endorse or promote products derived from this software without -# specific prior written permission from Walt Disney Pictures. -# -# Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. -# IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +# Copyright Disney Enterprises, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License +# and the following modification to it: Section 6 Trademarks. +# deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the +# trade names, trademarks, service marks, or product names of the +# Licensor and its affiliates, except as required for reproducing +# the content of the NOTICE file. +# +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 foreach(item basic) ADD_EXECUTABLE(${item} "${item}.cpp") diff --git a/src/tests/SeTests.h b/src/tests/SeTests.h index ff68812b..c84f30f2 100644 --- a/src/tests/SeTests.h +++ b/src/tests/SeTests.h @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef _SeTests_h_ #define _SeTests_h_ diff --git a/src/tests/basic.cpp b/src/tests/basic.cpp index 758c2c5d..d53abe55 100644 --- a/src/tests/basic.cpp +++ b/src/tests/basic.cpp @@ -1,36 +1,18 @@ /* - SEEXPR SOFTWARE - Copyright 2011 Disney Enterprises, Inc. All rights reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation - Studios" or the names of its contributors may NOT be used to - endorse or promote products derived from this software without - specific prior written permission from Walt Disney Pictures. - - Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND - CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. - IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +* Copyright Disney Enterprises, Inc. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License +* and the following modification to it: Section 6 Trademarks. +* deleted and replaced with: +* +* 6. Trademarks. This License does not grant permission to use the +* trade names, trademarks, service marks, or product names of the +* Licensor and its affiliates, except as required for reproducing +* the content of the NOTICE file. +* +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 */ #include #include @@ -45,7 +27,7 @@ struct SimpleExpression:public SeExpression { double value; void eval(const SeExprVarNode* node,SeVec3d& result) - {result[0]=value;} + {UNUSED(node); result[0]=value;} }; mutable Var x,y; @@ -63,10 +45,12 @@ struct SimpleExpression:public SeExpression {return x+y;} // Custom function resolver +/* SeExprFunc* resolveFunc(const std::string& name) const { if(name=="custom") return &customFunc; } +*/ // Constructor SimpleExpression(const std::string& str)