From dd99e2a6b5054927bba83d44a7a03bc365c28a77 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Mon, 12 Jan 2009 02:17:03 -0700 Subject: Applied Aimee's patch for doing simple math in the build editor --- ChangeLog.txt | 27 ++++ linden/indra/llmath/CMakeLists.txt | 4 + linden/indra/llmath/llcalc.cpp | 155 +++++++++++++++++++++ linden/indra/llmath/llcalc.h | 85 +++++++++++ linden/indra/llmath/llcalcparser.cpp | 45 ++++++ linden/indra/llmath/llcalcparser.h | 155 +++++++++++++++++++++ linden/indra/llui/lllineeditor.cpp | 33 ++++- linden/indra/llui/lllineeditor.h | 4 + linden/indra/llui/llspinctrl.cpp | 17 ++- linden/indra/newview/llappviewer.cpp | 3 + linden/indra/newview/llpanelface.cpp | 20 +++ linden/indra/newview/llpanelobject.cpp | 49 ++++++- .../skins/default/xui/en-us/floater_tools.xml | 18 +-- 13 files changed, 596 insertions(+), 19 deletions(-) create mode 100644 linden/indra/llmath/llcalc.cpp create mode 100644 linden/indra/llmath/llcalc.h create mode 100644 linden/indra/llmath/llcalcparser.cpp create mode 100644 linden/indra/llmath/llcalcparser.h diff --git a/ChangeLog.txt b/ChangeLog.txt index b8002f6..84f64b0 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -8,6 +8,33 @@ Ditto. + Aimee Trescothick + * linden/indra/llmath/llcalc.cpp: + Ability to do simple math in build editor. + * linden/indra/llmath/llcalc.h: + Ditto. + * linden/indra/llmath/llcalcparser.cpp: + Ditto. + * linden/indra/llmath/llcalcparser.h: + Ditto. + * linden/indra/llmath/CMakeLists.txt: + Ditto. + * linden/indra/llui/lllineeditor.cpp: + Ditto. + * linden/indra/llui/lllineeditor.h: + Ditto. + * linden/indra/llui/llspinctrl.cpp: + Ditto. + * linden/indra/newview/llappviewer.cpp: + Ditto. + * linden/indra/newview/llpanelface.cpp: + Ditto. + * linden/indra/newview/llpanelobject.cpp: + Ditto. + * linden/indra/newview/skins/default/xui/en-us/floater_tools.xml: + Ditto. + + 2009-01-08 McCabe Maxsted * linden/indra/cmake/CopyWinLibs.cmake: diff --git a/linden/indra/llmath/CMakeLists.txt b/linden/indra/llmath/CMakeLists.txt index 6a329fa..e5ec3e1 100644 --- a/linden/indra/llmath/CMakeLists.txt +++ b/linden/indra/llmath/CMakeLists.txt @@ -11,6 +11,8 @@ include_directories( set(llmath_SOURCE_FILES llbboxlocal.cpp + llcalc.cpp + llcalcparser.cpp llcamera.cpp llcoordframe.cpp llline.cpp @@ -40,6 +42,8 @@ set(llmath_HEADER_FILES camera.h coordframe.h llbboxlocal.h + llcalc.h + llcalcparser.h llcamera.h llcoord.h llcoordframe.h diff --git a/linden/indra/llmath/llcalc.cpp b/linden/indra/llmath/llcalc.cpp new file mode 100644 index 0000000..feb072a --- /dev/null +++ b/linden/indra/llmath/llcalc.cpp @@ -0,0 +1,155 @@ +/* + * LLCalc.cpp + * SecondLife + * + * Created by Aimee Walton on 28/09/2008. + * Copyright 2008 Aimee Walton. + * + */ + +#include "linden_common.h" + +#include "llcalc.h" + +#include +#include + +#include "llcalcparser.h" +#include "llmath.h" + + +// Variable names for use in the build floater +const char* LLCalc::X_POS = "X"; +const char* LLCalc::Y_POS = "Y"; +const char* LLCalc::Z_POS = "Z"; +const char* LLCalc::X_SCALE = "XS"; +const char* LLCalc::Y_SCALE = "YS"; +const char* LLCalc::Z_SCALE = "ZS"; +const char* LLCalc::X_ROT = "XR"; +const char* LLCalc::Y_ROT = "YR"; +const char* LLCalc::Z_ROT = "ZR"; +const char* LLCalc::HOLLOW = "HLW"; +const char* LLCalc::CUT_BEGIN = "CB"; +const char* LLCalc::CUT_END = "CE"; +const char* LLCalc::PATH_BEGIN = "PB"; +const char* LLCalc::PATH_END = "PE"; +const char* LLCalc::TWIST_BEGIN = "TB"; +const char* LLCalc::TWIST_END = "TE"; +const char* LLCalc::X_SHEAR = "XSH"; +const char* LLCalc::Y_SHEAR = "YSH"; +const char* LLCalc::X_TAPER = "XTP"; +const char* LLCalc::Y_TAPER = "YTP"; +const char* LLCalc::RADIUS_OFFSET = "ROF"; +const char* LLCalc::REVOLUTIONS = "REV"; +const char* LLCalc::SKEW = "SKW"; +const char* LLCalc::X_HOLE = "XHL"; +const char* LLCalc::Y_HOLE = "YHL"; +const char* LLCalc::TEX_U_SCALE = "TSU"; +const char* LLCalc::TEX_V_SCALE = "TSV"; +const char* LLCalc::TEX_U_OFFSET = "TOU"; +const char* LLCalc::TEX_V_OFFSET = "TOV"; +const char* LLCalc::TEX_ROTATION = "TROT"; +const char* LLCalc::TEX_TRANSPARENCY = "TRNS"; +const char* LLCalc::TEX_GLOW = "GLOW"; + + +LLCalc* LLCalc::sInstance = NULL; + +LLCalc::LLCalc() : mLastErrorPos(0) +{ +// mUserVariables = new calc_map_t; + mVariables = new calc_map_t; + mConstants = new calc_map_t; + + // Init table of constants + (*mConstants)["PI"] = F_PI; + (*mConstants)["TWO_PI"] = F_TWO_PI; + (*mConstants)["PI_BY_TWO"] = F_PI_BY_TWO; + (*mConstants)["SQRT2"] = F_SQRT2; + (*mConstants)["DEG_TO_RAD"] = DEG_TO_RAD; + (*mConstants)["RAD_TO_DEG"] = RAD_TO_DEG; + (*mConstants)["GRAVITY"] = GRAVITY; +} + +LLCalc::~LLCalc() +{ + delete mConstants; + delete mVariables; +// delete mUserVariables; +} + +//static +void LLCalc::cleanUp() +{ + delete sInstance; + sInstance = NULL; +} + +//static +LLCalc* LLCalc::getInstance() +{ + if (!sInstance) sInstance = new LLCalc(); + return sInstance; +} + +void LLCalc::setVar(const std::string& name, const F32& value) +{ + (*mVariables)[name] = value; +} + +void LLCalc::clearVar(const std::string& name) +{ + mVariables->erase(name); +} + +void LLCalc::clearAllVariables() +{ + mVariables->clear(); +} + +/* +void LLCalc::updateVariables(LLSD& vars) +{ + LLSD::map_iterator cIt = vars.beginMap(); + for(; cIt != vars.endMap(); cIt++) + { + setVar(cIt->first, (F32)(LLSD::Real)cIt->second); + } +} +*/ + +bool LLCalc::evalString(const std::string& expression, F32& result) +{ + using namespace boost::spirit; + + std::string expr_upper = expression; + LLStringUtil::toUpper(expr_upper); + + LLCalcParser calc(result, mConstants, mVariables); + + mLastErrorPos = 0; + std::string::iterator start = expr_upper.begin(); + parse_info info; + + try + { + info = parse(start, expr_upper.end(), calc, space_p); + lldebugs << "Math expression: " << expression << " = " << result << llendl; + } + catch(parser_error &e) + { + mLastErrorPos = e.where - expr_upper.begin(); + + llinfos << "Calc parser exception: " << e.descriptor << " at " << mLastErrorPos << " in expression: " << expression << llendl; + return false; + } + + if (!info.full) + { + mLastErrorPos = info.stop - expr_upper.begin(); + llinfos << "Unhandled syntax error at " << mLastErrorPos << " in expression: " << expression << llendl; + return false; + } + + return true; +} diff --git a/linden/indra/llmath/llcalc.h b/linden/indra/llmath/llcalc.h new file mode 100644 index 0000000..a376895 --- /dev/null +++ b/linden/indra/llmath/llcalc.h @@ -0,0 +1,85 @@ +/* + * LLCalc.h + * SecondLife + * + * Created by Aimee Walton on 28/09/2008. + * Copyright 2008 Aimee Walton. + * + */ + +#ifndef LL_CALC_H +#define LL_CALC_H + +#include +#include + +//#include "llsd.h" + +class LLCalc +{ +public: + LLCalc(); + ~LLCalc(); + + // Variable name constants + static const char* X_POS; + static const char* Y_POS; + static const char* Z_POS; + static const char* X_SCALE; + static const char* Y_SCALE; + static const char* Z_SCALE; + static const char* X_ROT; + static const char* Y_ROT; + static const char* Z_ROT; + static const char* HOLLOW; + static const char* CUT_BEGIN; + static const char* CUT_END; + static const char* PATH_BEGIN; + static const char* PATH_END; + static const char* TWIST_BEGIN; + static const char* TWIST_END; + static const char* X_SHEAR; + static const char* Y_SHEAR; + static const char* X_TAPER; + static const char* Y_TAPER; + static const char* RADIUS_OFFSET; + static const char* REVOLUTIONS; + static const char* SKEW; + static const char* X_HOLE; + static const char* Y_HOLE; + static const char* TEX_U_SCALE; + static const char* TEX_V_SCALE; + static const char* TEX_U_OFFSET; + static const char* TEX_V_OFFSET; + static const char* TEX_ROTATION; + static const char* TEX_TRANSPARENCY; + static const char* TEX_GLOW; + + void setVar(const std::string& name, const F32& value); + void clearVar(const std::string& name); + void clearAllVariables(); +// void updateVariables(LLSD& vars); + + bool evalString(const std::string& expression, F32& result); + std::string::size_type getLastErrorPos() { return mLastErrorPos; } + + static LLCalc* getInstance(); + static void cleanUp(); + + typedef std::map calc_map_t; + +private: + std::string::size_type mLastErrorPos; + + calc_map_t* mConstants; + calc_map_t* mVariables; + + // *TODO: Add support for storing user defined variables, and stored functions. + // Will need UI work, and a means to save them between sessions. +// calc_map_t* mUserVariables; + + // "There shall be only one" + static LLCalc* sInstance; +}; + +#endif // LL_CALC_H diff --git a/linden/indra/llmath/llcalcparser.cpp b/linden/indra/llmath/llcalcparser.cpp new file mode 100644 index 0000000..1546c09 --- /dev/null +++ b/linden/indra/llmath/llcalcparser.cpp @@ -0,0 +1,45 @@ +/* + * LLCalcParser.cpp + * SecondLife + * + * Created by Aimee Walton on 28/09/2008. + * Copyright 2008 Aimee Walton. + * + */ + +#include "linden_common.h" + +#include "llcalcparser.h" + +F32 LLCalcParser::lookup(const std::string::iterator& start, const std::string::iterator& end) const +{ + LLCalc::calc_map_t::iterator iter; + + std::string name(start, end); + + if (mConstants) + { + iter = mConstants->find(name); + if (iter != mConstants->end()) + { + return (*iter).second; + } + } + else + { + // This should never happen! + boost::spirit::throw_(end, std::string("Missing constants table")); + } + + if (mVariables) + { + iter = mVariables->find(name); + if (iter != mVariables->end()) + { + return (*iter).second; + } + } + + boost::spirit::throw_(end, std::string("Unknown symbol " + name)); + return 0.f; +} diff --git a/linden/indra/llmath/llcalcparser.h b/linden/indra/llmath/llcalcparser.h new file mode 100644 index 0000000..c405b62 --- /dev/null +++ b/linden/indra/llmath/llcalcparser.h @@ -0,0 +1,155 @@ +/* + * LLCalcParser.h + * SecondLife + * + * Created by Aimee Walton on 28/09/2008. + * Copyright 2008 Aimee Walton. + * + */ + +#ifndef LL_CALCPARSER_H +#define LL_CALCPARSER_H + +#include +#include +#include +#include +#include +//#include +#include +#include + +#include "llcalc.h" +#include "llmath.h" + +struct LLCalcParser : boost::spirit::grammar +{ + LLCalcParser(F32& result, LLCalc::calc_map_t* constants, LLCalc::calc_map_t* vars) : + mResult(result), mConstants(constants), mVariables(vars) {}; + + struct value_closure : boost::spirit::closure + { + member1 value; + }; + + template + struct definition + { + // Rule declarations + boost::spirit::rule statement, identifier; + boost::spirit::rule expression, term, + power, + unary_expr, + factor, + /*unary_func, + /binary_func,*/ + group; + + // start() should return the starting symbol + boost::spirit::rule const& start() const { return statement; } + + definition(LLCalcParser const& self) + { + using namespace boost::spirit; + using namespace phoenix; + + assertion assert_domain("Domain error"); +// assertion assert_symbol("Unknown symbol"); + assertion assert_syntax("Syntax error"); + + identifier = + lexeme_d[(alpha_p | '_') >> *(alnum_p | '_')] + ; + + group = + '(' >> expression[group.value = arg1] >> assert_syntax(ch_p(')')) + ; + + /*unary_func = + ((str_p("SIN") >> '(' >> expression[unary_func.value = bind(&sin)(DEG_TO_RAD * arg1)]) | + (str_p("COS") >> '(' >> expression[unary_func.value = bind(&cos)(DEG_TO_RAD * arg1)]) | + (str_p("TAN") >> '(' >> expression[unary_func.value = bind(&tan)(DEG_TO_RAD * arg1)]) | + (str_p("ASIN") >> '(' >> expression[unary_func.value = (bind(&asin)(arg1)) * RAD_TO_DEG]) | + (str_p("ACOS") >> '(' >> expression[unary_func.value = bind(&acos)(arg1) * RAD_TO_DEG]) | + (str_p("ATAN") >> '(' >> expression[unary_func.value = bind(&atan)(arg1) * RAD_TO_DEG]) | + (str_p("SQRT") >> '(' >> expression[unary_func.value = bind(&sqrt)(arg1)]) | + (str_p("LOG") >> '(' >> expression[unary_func.value = bind(&log)(arg1)]) | + (str_p("EXP") >> '(' >> expression[unary_func.value = bind(&exp)(arg1)]) | + (str_p("ABS") >> '(' >> expression[unary_func.value = bind(&fabs)(arg1)]) + ) >> assert_syntax(ch_p(')')) + ; + + binary_func = + ((str_p("ATAN2") >> '(' >> expression[binary_func.value = arg1] >> ',' >> + expression[binary_func.value = bind(&atan2)(binary_func.value, arg1) * RAD_TO_DEG]) | + (str_p("MIN") >> '(' >> expression[binary_func.value = arg1] >> ',' >> + expression[binary_func.value = bind(&LLCalcParser::min)(self, binary_func.value, arg1)]) | + (str_p("MAX") >> '(' >> expression[binary_func.value = arg1] >> ',' >> + expression[binary_func.value = bind(&LLCalcParser::max)(self, binary_func.value, arg1)]) + ) >> assert_syntax(ch_p(')')) + ;*/ + + // *TODO: Localisation of the decimal point? + // Problem, LLLineEditor::postvalidateFloat accepts a comma when appropriate + // for the current locale. However to do that here could clash with using + // the comma as a separator when passing arguments to functions. + factor = + (ureal_p[factor.value = arg1] | + group[factor.value = arg1] | + /*unary_func[factor.value = arg1] | + binary_func[factor.value = arg1] |*/ + // Lookup throws an Unknown Symbol error if it is unknown, while this works fine, + // would be "neater" to handle symbol lookup from here with an assertive parser. +// constants_p[factor.value = arg1]| + identifier[factor.value = bind(&LLCalcParser::lookup)(self, arg1, arg2)] + ) >> + // Detect and throw math errors. + assert_domain(eps_p(bind(&LLCalcParser::checkNaN)(self, factor.value))) + ; + + unary_expr = + !ch_p('+') >> factor[unary_expr.value = arg1] | + '-' >> factor[unary_expr.value = -arg1] + ; + + power = + unary_expr[power.value = arg1] >> + *('^' >> assert_syntax(unary_expr[power.value = bind(&powf)(power.value, arg1)])) + ; + + term = + power[term.value = arg1] >> + *(('*' >> assert_syntax(power[term.value *= arg1])) | + ('/' >> assert_syntax(power[term.value /= arg1])) + ) + ; + + expression = + assert_syntax(term[expression.value = arg1]) >> + *(('+' >> assert_syntax(term[expression.value += arg1])) | + ('-' >> assert_syntax(term[expression.value -= arg1])) + ) + ; + + statement = + !ch_p('=') >> ( expression )[var(self.mResult) = arg1] >> (end_p) + ; + } + }; + +private: + // Member functions for semantic actions + F32 lookup(const std::string::iterator&, const std::string::iterator&) const; + F32 min(const F32& a, const F32& b) const { return llmin(a, b); } + F32 max(const F32& a, const F32& b) const { return llmax(a, b); } + + bool checkNaN(const F32& a) const { return !llisnan(a); } + + LLCalc::calc_map_t* mConstants; + LLCalc::calc_map_t* mVariables; +// LLCalc::calc_map_t* mUserVariables; + + F32& mResult; +}; + +#endif // LL_CALCPARSER_H diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 12d1929..9c8ee94 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp @@ -41,6 +41,7 @@ #include "llgl.h" #include "lltimer.h" +#include "llcalc.h" //#include "llclipboard.h" #include "llcontrol.h" #include "llbutton.h" @@ -129,6 +130,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, mDrawAsterixes( FALSE ), mHandleEditKeysDirectly( FALSE ), mSelectAllonFocusReceived( FALSE ), + mSelectAllonCommit( TRUE ), mPassDelete(FALSE), mReadOnly(FALSE), mImage( sImage ), @@ -226,7 +228,10 @@ void LLLineEditor::onCommit() updateHistory(); LLUICtrl::onCommit(); - selectAll(); + + // Selection on commit needs to be turned off when evaluating maths + // expressions, to allow indication of the error position + if (mSelectAllonCommit) selectAll(); } @@ -2082,6 +2087,32 @@ BOOL LLLineEditor::prevalidateASCII(const LLWString &str) return rv; } +BOOL LLLineEditor::evaluateFloat() +{ + bool success; + F32 result = 0.f; + std::string expr = getText(); + + success = LLCalc::getInstance()->evalString(expr, result); + + if (!success) + { + // Move the cursor to near the error on failure + setCursor(LLCalc::getInstance()->getLastErrorPos()); + // *TODO: Translated error message indicating the type of error? Select error text? + } + else + { + // Replace the expression with the result + std::ostringstream result_str; + result_str << result; + setText(result_str.str()); + selectAll(); + } + + return success; +} + void LLLineEditor::onMouseCaptureLost() { endSelection(); diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index 09a240b..6738151 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h @@ -188,6 +188,7 @@ public: void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; } void setSelectAllonFocusReceived(BOOL b); + void setSelectAllonCommit(BOOL b) { mSelectAllonCommit = b; } void setKeystrokeCallback(void (*keystroke_callback)(LLLineEditor* caller, void* user_data)); @@ -208,6 +209,8 @@ public: static BOOL prevalidateASCII(const LLWString &str); static BOOL postvalidateFloat(const std::string &str); + + BOOL evaluateFloat(); // line history support: void setEnableLineHistory( BOOL enabled ) { mHaveHistory = enabled; } // switches line history on or off @@ -297,6 +300,7 @@ protected: BOOL mHandleEditKeysDirectly; // If true, the standard edit keys (Ctrl-X, Delete, etc,) are handled here instead of routed by the menu system BOOL mSelectAllonFocusReceived; + BOOL mSelectAllonCommit; BOOL mPassDelete; BOOL mReadOnly; diff --git a/linden/indra/llui/llspinctrl.cpp b/linden/indra/llui/llspinctrl.cpp index a106af4..b12d095 100644 --- a/linden/indra/llui/llspinctrl.cpp +++ b/linden/indra/llui/llspinctrl.cpp @@ -49,7 +49,7 @@ #include "llfocusmgr.h" #include "llresmgr.h" -const U32 MAX_STRING_LENGTH = 32; +const U32 MAX_STRING_LENGTH = 255; static LLRegisterWidget r2("spinner"); @@ -123,7 +123,7 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std:: mEditor = new LLLineEditor( std::string("SpinCtrl Editor"), editor_rect, LLStringUtil::null, font, MAX_STRING_LENGTH, &LLSpinCtrl::onEditorCommit, NULL, NULL, this, - &LLLineEditor::prevalidateFloat ); + &LLLineEditor::prevalidateASCII ); mEditor->setFollowsLeft(); mEditor->setFollowsBottom(); mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this ); @@ -132,6 +132,7 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std:: // it's easier to understand //mEditor->setSelectAllonFocusReceived(TRUE); mEditor->setIgnoreTab(TRUE); + mEditor->setSelectAllonCommit(FALSE); addChild(mEditor); updateEditor(); @@ -292,9 +293,10 @@ void LLSpinCtrl::onEditorCommit( LLUICtrl* caller, void *userdata ) LLSpinCtrl* self = (LLSpinCtrl*) userdata; llassert( caller == self->mEditor ); - std::string text = self->mEditor->getText(); - if( LLLineEditor::postvalidateFloat( text ) ) + if( self->mEditor->evaluateFloat() ) { + std::string text = self->mEditor->getText(); + LLLocale locale(LLLocale::USER_LOCALE); F32 val = (F32) atof(text.c_str()); @@ -322,9 +324,12 @@ void LLSpinCtrl::onEditorCommit( LLUICtrl* caller, void *userdata ) success = TRUE; } } - self->updateEditor(); - if( !success ) + if( success ) + { + self->updateEditor(); + } + else { self->reportInvalidData(); } diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 2cf418e..64402e3 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -109,6 +109,7 @@ #include "llpostprocess.h" #include "llwlparammanager.h" #include "llwaterparammanager.h" +#include "llcalc.h" #include "lldebugview.h" #include "llconsole.h" @@ -1176,6 +1177,8 @@ bool LLAppViewer::cleanup() LLNotifyBox::cleanup(); LLWorldMap::getInstance()->reset(); // release any images + + LLCalc::cleanUp(); llinfos << "Global stuff deleted" << llendflush; diff --git a/linden/indra/newview/llpanelface.cpp b/linden/indra/newview/llpanelface.cpp index 4742627..e9555c6 100644 --- a/linden/indra/newview/llpanelface.cpp +++ b/linden/indra/newview/llpanelface.cpp @@ -35,6 +35,7 @@ #include "llpanelface.h" // library includes +#include "llcalc.h" #include "llerror.h" #include "llfocusmgr.h" #include "llrect.h" @@ -381,6 +382,7 @@ void LLPanelFace::sendTextureInfo() void LLPanelFace::getState() { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLCalc* calcp = LLCalc::getInstance(); if( objectp && objectp->getPCode() == LL_PCODE_VOLUME @@ -754,6 +756,15 @@ void LLPanelFace::getState() childSetEnabled("button apply",enabled); } } + + // Set variable values for numeric expressions + calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); + calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal()); + calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal()); + calcp->setVar(LLCalc::TEX_V_OFFSET, childGetValue("TexOffsetV").asReal()); + calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal()); + calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal()); + calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal()); } else { @@ -787,6 +798,15 @@ void LLPanelFace::getState() childSetEnabled("button align",FALSE); childSetEnabled("button apply",FALSE); + + // Set variable values for numeric expressions + calcp->clearVar(LLCalc::TEX_U_SCALE); + calcp->clearVar(LLCalc::TEX_V_SCALE); + calcp->clearVar(LLCalc::TEX_U_OFFSET); + calcp->clearVar(LLCalc::TEX_V_OFFSET); + calcp->clearVar(LLCalc::TEX_ROTATION); + calcp->clearVar(LLCalc::TEX_TRANSPARENCY); + calcp->clearVar(LLCalc::TEX_GLOW); } } diff --git a/linden/indra/newview/llpanelobject.cpp b/linden/indra/newview/llpanelobject.cpp index cc9d969..8efa39a 100644 --- a/linden/indra/newview/llpanelobject.cpp +++ b/linden/indra/newview/llpanelobject.cpp @@ -46,6 +46,7 @@ // project includes #include "llagent.h" #include "llbutton.h" +#include "llcalc.h" #include "llcheckboxctrl.h" #include "llcolorswatch.h" #include "llcombobox.h" @@ -341,6 +342,8 @@ void LLPanelObject::getState( ) } } + LLCalc* calcp = LLCalc::getInstance(); + LLVOVolume *volobjp = NULL; if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) { @@ -357,6 +360,7 @@ void LLPanelObject::getState( ) // Disable all text input fields clearCtrls(); + calcp->clearAllVariables(); return; } @@ -372,12 +376,18 @@ void LLPanelObject::getState( ) mCtrlPosX->set( vec.mV[VX] ); mCtrlPosY->set( vec.mV[VY] ); mCtrlPosZ->set( vec.mV[VZ] ); + calcp->setVar(LLCalc::X_POS, vec.mV[VX]); + calcp->setVar(LLCalc::Y_POS, vec.mV[VY]); + calcp->setVar(LLCalc::Z_POS, vec.mV[VZ]); } else { mCtrlPosX->clear(); mCtrlPosY->clear(); mCtrlPosZ->clear(); + calcp->clearVar(LLCalc::X_POS); + calcp->clearVar(LLCalc::Y_POS); + calcp->clearVar(LLCalc::Z_POS); } @@ -392,12 +402,18 @@ void LLPanelObject::getState( ) mCtrlScaleX->set( vec.mV[VX] ); mCtrlScaleY->set( vec.mV[VY] ); mCtrlScaleZ->set( vec.mV[VZ] ); + calcp->setVar(LLCalc::X_SCALE, vec.mV[VX]); + calcp->setVar(LLCalc::Y_SCALE, vec.mV[VY]); + calcp->setVar(LLCalc::Z_SCALE, vec.mV[VZ]); } else { mCtrlScaleX->clear(); mCtrlScaleY->clear(); mCtrlScaleZ->clear(); + calcp->setVar(LLCalc::X_SCALE, 0.f); + calcp->setVar(LLCalc::Y_SCALE, 0.f); + calcp->setVar(LLCalc::Z_SCALE, 0.f); } mLabelSize->setEnabled( enable_scale ); @@ -417,12 +433,18 @@ void LLPanelObject::getState( ) mCtrlRotX->set( mCurEulerDegrees.mV[VX] ); mCtrlRotY->set( mCurEulerDegrees.mV[VY] ); mCtrlRotZ->set( mCurEulerDegrees.mV[VZ] ); + calcp->setVar(LLCalc::X_ROT, mCurEulerDegrees.mV[VX]); + calcp->setVar(LLCalc::Y_ROT, mCurEulerDegrees.mV[VY]); + calcp->setVar(LLCalc::Z_ROT, mCurEulerDegrees.mV[VZ]); } else { mCtrlRotX->clear(); mCtrlRotY->clear(); mCtrlRotZ->clear(); + calcp->clearVar(LLCalc::X_ROT); + calcp->clearVar(LLCalc::Y_ROT); + calcp->clearVar(LLCalc::Z_ROT); } mLabelRotation->setEnabled( enable_rotate ); @@ -678,8 +700,9 @@ void LLPanelObject::getState( ) F32 end_t = volume_params.getEndT(); // Hollowness - F32 hollow = volume_params.getHollow(); - mSpinHollow->set( 100.f * hollow ); + F32 hollow = 100.f * volume_params.getHollow(); + mSpinHollow->set( hollow ); + calcp->setVar(LLCalc::HOLLOW, hollow); // All hollow objects allow a shape to be selected. if (hollow > 0.f) @@ -732,6 +755,10 @@ void LLPanelObject::getState( ) mSpinCutEnd ->set( cut_end ); mCtrlPathBegin ->set( adv_cut_begin ); mCtrlPathEnd ->set( adv_cut_end ); + calcp->setVar(LLCalc::CUT_BEGIN, cut_begin); + calcp->setVar(LLCalc::CUT_END, cut_end); + calcp->setVar(LLCalc::PATH_BEGIN, adv_cut_begin); + calcp->setVar(LLCalc::PATH_END, adv_cut_end); // Twist F32 twist = volume_params.getTwist(); @@ -750,18 +777,24 @@ void LLPanelObject::getState( ) mSpinTwist ->set( twist ); mSpinTwistBegin ->set( twist_begin ); + calcp->setVar(LLCalc::TWIST_END, twist); + calcp->setVar(LLCalc::TWIST_BEGIN, twist_begin); // Shear F32 shear_x = volume_params.getShearX(); F32 shear_y = volume_params.getShearY(); mSpinShearX->set( shear_x ); mSpinShearY->set( shear_y ); + calcp->setVar(LLCalc::X_SHEAR, shear_x); + calcp->setVar(LLCalc::Y_SHEAR, shear_y); // Taper F32 taper_x = volume_params.getTaperX(); F32 taper_y = volume_params.getTaperY(); mSpinTaperX->set( taper_x ); mSpinTaperY->set( taper_y ); + calcp->setVar(LLCalc::X_TAPER, taper_x); + calcp->setVar(LLCalc::Y_TAPER, taper_y); // Radius offset. F32 radius_offset = volume_params.getRadiusOffset(); @@ -791,10 +824,12 @@ void LLPanelObject::getState( ) } } mSpinRadiusOffset->set( radius_offset); + calcp->setVar(LLCalc::RADIUS_OFFSET, radius_offset); // Revolutions F32 revolutions = volume_params.getRevolutions(); mSpinRevolutions->set( revolutions ); + calcp->setVar(LLCalc::REVOLUTIONS, revolutions); // Skew F32 skew = volume_params.getSkew(); @@ -819,6 +854,7 @@ void LLPanelObject::getState( ) } } mSpinSkew->set( skew ); + calcp->setVar(LLCalc::SKEW, skew); } // Compute control visibility, label names, and twist range. @@ -924,6 +960,8 @@ void LLPanelObject::getState( ) case MI_RING: mSpinScaleX->set( scale_x ); mSpinScaleY->set( scale_y ); + calcp->setVar(LLCalc::X_HOLE, scale_x); + calcp->setVar(LLCalc::Y_HOLE, scale_y); mSpinScaleX->setMinValue(OBJECT_MIN_HOLE_SIZE); mSpinScaleX->setMaxValue(OBJECT_MAX_HOLE_SIZE_X); mSpinScaleY->setMinValue(OBJECT_MIN_HOLE_SIZE); @@ -934,6 +972,8 @@ void LLPanelObject::getState( ) { mSpinScaleX->set( 1.f - scale_x ); mSpinScaleY->set( 1.f - scale_y ); + calcp->setVar(LLCalc::X_HOLE, 1.f - scale_x); + calcp->setVar(LLCalc::Y_HOLE, 1.f - scale_y); mSpinScaleX->setMinValue(-1.f); mSpinScaleX->setMaxValue(1.f); mSpinScaleY->setMinValue(-1.f); @@ -1148,7 +1188,7 @@ void LLPanelObject::getState( ) mSculptTextureRevert = LLUUID::null; } - + //---------------------------------------------------------------------------- mObject = objectp; @@ -1954,6 +1994,9 @@ void LLPanelObject::onCommitRotation( LLUICtrl* ctrl, void* userdata ) LLPanelObject* self = (LLPanelObject*) userdata; BOOL btn_down = ((LLSpinCtrl*)ctrl)->isMouseHeldDown() ; self->sendRotation(btn_down); + + // Needed to ensure all rotations are shown consistently in range + self->refresh(); } // static diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml index 742da45..05cf101 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -614,15 +614,15 @@ + text_enabled_color="110, 15, 15, 255" width="96" /> + text_enabled_color="0, 100, 40, 255" width="96" /> + text_enabled_color="0, 67, 132, 255" width="96" /> + text_enabled_color="1, 1, 1, 1" width="96" /> + text_enabled_color="1, 1, 1, 1" width="96" /> + text_enabled_color="1, 1, 1, 1" width="96" /> + text_enabled_color="1, 1, 1, 1" width="96" /> + text_enabled_color="1, 1, 1, 1" width="96" /> + text_enabled_color="1, 1, 1, 1" width="96" />