llpanelobject.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 // file include
00035 #include "llpanelobject.h"
00036 
00037 // linden library includes
00038 #include "lleconomy.h"
00039 #include "llerror.h"
00040 #include "llfontgl.h"
00041 #include "llpermissionsflags.h"
00042 #include "llstring.h"
00043 #include "llvolume.h"
00044 #include "m3math.h"
00045 
00046 // project includes
00047 #include "llagent.h"
00048 #include "llbutton.h"
00049 #include "llcheckboxctrl.h"
00050 #include "llcolorswatch.h"
00051 #include "llcombobox.h"
00052 #include "llfocusmgr.h"
00053 #include "llmanipscale.h"
00054 #include "llpanelinventory.h"
00055 #include "llpreviewscript.h"
00056 #include "llresmgr.h"
00057 #include "llselectmgr.h"
00058 #include "llspinctrl.h"
00059 #include "lltexturectrl.h"
00060 #include "lltextbox.h"
00061 #include "lltool.h"
00062 #include "lltoolcomp.h"
00063 #include "lltoolmgr.h"
00064 #include "llui.h"
00065 #include "llviewerobject.h"
00066 #include "llviewerregion.h"
00067 #include "llviewerwindow.h"
00068 #include "llvovolume.h"
00069 #include "llworld.h"
00070 #include "pipeline.h"
00071 #include "llviewercontrol.h"
00072 #include "lluictrlfactory.h"
00073 #include "llfirstuse.h"
00074 
00075 #include "lldrawpool.h"
00076 
00077 //
00078 // Constants
00079 //
00080 enum {
00081         MI_BOX,
00082         MI_CYLINDER,
00083         MI_PRISM,
00084         MI_SPHERE,
00085         MI_TORUS,
00086         MI_TUBE,
00087         MI_RING,
00088         MI_SCULPT,
00089         MI_NONE,
00090         MI_VOLUME_COUNT
00091 };
00092 
00093 enum {
00094         MI_HOLE_SAME,
00095         MI_HOLE_CIRCLE,
00096         MI_HOLE_SQUARE,
00097         MI_HOLE_TRIANGLE,
00098         MI_HOLE_COUNT
00099 };
00100 
00101 //*TODO:translate (depricated, so very low priority)
00102 static const LLString LEGACY_FULLBRIGHT_DESC("Fullbright (Legacy)");
00103 
00104 BOOL    LLPanelObject::postBuild()
00105 {
00106         setMouseOpaque(FALSE);
00107 
00108         //--------------------------------------------------------
00109         // Top
00110         //--------------------------------------------------------
00111         
00112         // Lock checkbox
00113         mCheckLock = getChild<LLCheckBoxCtrl>("checkbox locked");
00114         childSetCommitCallback("checkbox locked",onCommitLock,this);
00115 
00116         // Physical checkbox
00117         mCheckPhysics = getChild<LLCheckBoxCtrl>("Physical Checkbox Ctrl");
00118         childSetCommitCallback("Physical Checkbox Ctrl",onCommitPhysics,this);
00119 
00120         // Temporary checkbox
00121         mCheckTemporary = getChild<LLCheckBoxCtrl>("Temporary Checkbox Ctrl");
00122         childSetCommitCallback("Temporary Checkbox Ctrl",onCommitTemporary,this);
00123 
00124         // Phantom checkbox
00125         mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");
00126         childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
00127         
00128         // Position
00129         mLabelPosition = getChild<LLTextBox>("label position");
00130         mCtrlPosX = getChild<LLSpinCtrl>("Pos X");
00131         childSetCommitCallback("Pos X",onCommitPosition,this);
00132         mCtrlPosY = getChild<LLSpinCtrl>("Pos Y");
00133         childSetCommitCallback("Pos Y",onCommitPosition,this);
00134         mCtrlPosZ = getChild<LLSpinCtrl>("Pos Z");
00135         childSetCommitCallback("Pos Z",onCommitPosition,this);
00136 
00137         // Scale
00138         mLabelSize = getChild<LLTextBox>("label size");
00139         mCtrlScaleX = getChild<LLSpinCtrl>("Scale X");
00140         childSetCommitCallback("Scale X",onCommitScale,this);
00141 
00142         // Scale Y
00143         mCtrlScaleY = getChild<LLSpinCtrl>("Scale Y");
00144         childSetCommitCallback("Scale Y",onCommitScale,this);
00145 
00146         // Scale Z
00147         mCtrlScaleZ = getChild<LLSpinCtrl>("Scale Z");
00148         childSetCommitCallback("Scale Z",onCommitScale,this);
00149 
00150         // Rotation
00151         mLabelRotation = getChild<LLTextBox>("label rotation");
00152         mCtrlRotX = getChild<LLSpinCtrl>("Rot X");
00153         childSetCommitCallback("Rot X",onCommitRotation,this);
00154         mCtrlRotY = getChild<LLSpinCtrl>("Rot Y");
00155         childSetCommitCallback("Rot Y",onCommitRotation,this);
00156         mCtrlRotZ = getChild<LLSpinCtrl>("Rot Z");
00157         childSetCommitCallback("Rot Z",onCommitRotation,this);
00158 
00159         //--------------------------------------------------------
00160                 
00161         // material type popup
00162         mLabelMaterial = getChild<LLTextBox>("label material");
00163         mComboMaterial = getChild<LLComboBox>("material");
00164         childSetCommitCallback("material",onCommitMaterial,this);
00165         mComboMaterial->removeall();
00166         // *TODO:translate
00167         for (LLMaterialTable::info_list_t::iterator iter = LLMaterialTable::basic.mMaterialInfoList.begin();
00168                  iter != LLMaterialTable::basic.mMaterialInfoList.end(); ++iter)
00169         {
00170                 LLMaterialInfo* minfop = *iter;
00171                 if (minfop->mMCode != LL_MCODE_LIGHT)
00172                 {
00173                         mComboMaterial->add(minfop->mName);
00174                 }
00175         }
00176         mComboMaterialItemCount = mComboMaterial->getItemCount();
00177 
00178         // Base Type
00179         mLabelBaseType = getChild<LLTextBox>("label basetype");
00180         mComboBaseType = getChild<LLComboBox>("comboBaseType");
00181         childSetCommitCallback("comboBaseType",onCommitParametric,this);
00182 
00183         // Cut
00184         mLabelCut = getChild<LLTextBox>("text cut");
00185         mSpinCutBegin = getChild<LLSpinCtrl>("cut begin");
00186         childSetCommitCallback("cut begin",onCommitParametric,this);
00187         mSpinCutBegin->setValidateBeforeCommit( precommitValidate );
00188         mSpinCutEnd = getChild<LLSpinCtrl>("cut end");
00189         childSetCommitCallback("cut end",onCommitParametric,this);
00190         mSpinCutEnd->setValidateBeforeCommit( &precommitValidate );
00191 
00192         // Hollow / Skew
00193         mLabelHollow = getChild<LLTextBox>("text hollow");
00194         mLabelSkew = getChild<LLTextBox>("text skew");
00195         mSpinHollow = getChild<LLSpinCtrl>("Scale 1");
00196         childSetCommitCallback("Scale 1",onCommitParametric,this);
00197         mSpinHollow->setValidateBeforeCommit( &precommitValidate );
00198         mSpinSkew = getChild<LLSpinCtrl>("Skew");
00199         childSetCommitCallback("Skew",onCommitParametric,this);
00200         mSpinSkew->setValidateBeforeCommit( &precommitValidate );
00201         mLabelHoleType = getChild<LLTextBox>("Hollow Shape");
00202 
00203         // Hole Type
00204         mComboHoleType = getChild<LLComboBox>("hole");
00205         childSetCommitCallback("hole",onCommitParametric,this);
00206 
00207         // Twist
00208         mLabelTwist = getChild<LLTextBox>("text twist");
00209         mSpinTwistBegin = getChild<LLSpinCtrl>("Twist Begin");
00210         childSetCommitCallback("Twist Begin",onCommitParametric,this);
00211         mSpinTwistBegin->setValidateBeforeCommit( precommitValidate );
00212         mSpinTwist = getChild<LLSpinCtrl>("Twist End");
00213         childSetCommitCallback("Twist End",onCommitParametric,this);
00214         mSpinTwist->setValidateBeforeCommit( &precommitValidate );
00215 
00216         // Scale
00217         mSpinScaleX = getChild<LLSpinCtrl>("Taper Scale X");
00218         childSetCommitCallback("Taper Scale X",onCommitParametric,this);
00219         mSpinScaleX->setValidateBeforeCommit( &precommitValidate );
00220         mSpinScaleY = getChild<LLSpinCtrl>("Taper Scale Y");
00221         childSetCommitCallback("Taper Scale Y",onCommitParametric,this);
00222         mSpinScaleY->setValidateBeforeCommit( &precommitValidate );
00223 
00224         // Shear
00225         mLabelShear = getChild<LLTextBox>("text topshear");
00226         mSpinShearX = getChild<LLSpinCtrl>("Shear X");
00227         childSetCommitCallback("Shear X",onCommitParametric,this);
00228         mSpinShearX->setValidateBeforeCommit( &precommitValidate );
00229         mSpinShearY = getChild<LLSpinCtrl>("Shear Y");
00230         childSetCommitCallback("Shear Y",onCommitParametric,this);
00231         mSpinShearY->setValidateBeforeCommit( &precommitValidate );
00232 
00233         // Path / Profile
00234         mCtrlPathBegin = getChild<LLSpinCtrl>("Path Limit Begin");
00235         childSetCommitCallback("Path Limit Begin",onCommitParametric,this);
00236         mCtrlPathBegin->setValidateBeforeCommit( &precommitValidate );
00237         mCtrlPathEnd = getChild<LLSpinCtrl>("Path Limit End");
00238         childSetCommitCallback("Path Limit End",onCommitParametric,this);
00239         mCtrlPathEnd->setValidateBeforeCommit( &precommitValidate );
00240 
00241         // Taper
00242         mLabelTaper = getChild<LLTextBox>("text taper2");
00243         mSpinTaperX = getChild<LLSpinCtrl>("Taper X");
00244         childSetCommitCallback("Taper X",onCommitParametric,this);
00245         mSpinTaperX->setValidateBeforeCommit( precommitValidate );
00246         mSpinTaperY = getChild<LLSpinCtrl>("Taper Y");
00247         childSetCommitCallback("Taper Y",onCommitParametric,this);
00248         mSpinTaperY->setValidateBeforeCommit( precommitValidate );
00249         
00250         // Radius Offset / Revolutions
00251         mLabelRadiusOffset = getChild<LLTextBox>("text radius delta");
00252         mLabelRevolutions = getChild<LLTextBox>("text revolutions");
00253         mSpinRadiusOffset = getChild<LLSpinCtrl>("Radius Offset");
00254         childSetCommitCallback("Radius Offset",onCommitParametric,this);
00255         mSpinRadiusOffset->setValidateBeforeCommit( &precommitValidate );
00256         mSpinRevolutions = getChild<LLSpinCtrl>("Revolutions");
00257         childSetCommitCallback("Revolutions",onCommitParametric,this);
00258         mSpinRevolutions->setValidateBeforeCommit( &precommitValidate );
00259 
00260         // Sculpt
00261         mCtrlSculptTexture = getChild<LLTextureCtrl>("sculpt texture control");
00262         if (mCtrlSculptTexture)
00263         {
00264                 mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE));
00265                 mCtrlSculptTexture->setCommitCallback( LLPanelObject::onCommitSculpt );
00266                 mCtrlSculptTexture->setOnCancelCallback( LLPanelObject::onCancelSculpt );
00267                 mCtrlSculptTexture->setOnSelectCallback( LLPanelObject::onSelectSculpt );
00268                 mCtrlSculptTexture->setDropCallback(LLPanelObject::onDropSculpt);
00269                 mCtrlSculptTexture->setCallbackUserData( this );
00270                 // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
00271                 mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
00272                 // Allow any texture to be used during non-immediate mode.
00273                 mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
00274                 LLAggregatePermissions texture_perms;
00275                 if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
00276                 {
00277                         BOOL can_copy =
00278                                 texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
00279                                 texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
00280                         BOOL can_transfer =
00281                                 texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
00282                                 texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
00283                         mCtrlSculptTexture->setCanApplyImmediately(can_copy && can_transfer);
00284                 }
00285                 else
00286                 {
00287                         mCtrlSculptTexture->setCanApplyImmediately(FALSE);
00288                 }
00289         }
00290 
00291         mLabelSculptType = getChild<LLTextBox>("label sculpt type");
00292         mCtrlSculptType = getChild<LLComboBox>( "sculpt type control");
00293         childSetCommitCallback("sculpt type control", onCommitSculptType, this);
00294 
00295         
00296         // Start with everyone disabled
00297         clearCtrls();
00298 
00299         return TRUE;
00300 }
00301 
00302 LLPanelObject::LLPanelObject(const std::string& name)
00303 :       LLPanel(name),
00304         mIsPhysical(FALSE),
00305         mIsTemporary(FALSE),
00306         mIsPhantom(FALSE),
00307         mCastShadows(TRUE),
00308         mSelectedType(MI_BOX)
00309 {
00310 }
00311 
00312 
00313 LLPanelObject::~LLPanelObject()
00314 {
00315         // Children all cleaned up by default view destructor.
00316 }
00317 
00318 void LLPanelObject::getState( )
00319 {
00320         LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
00321         LLViewerObject* root_objectp = objectp;
00322         if(!objectp)
00323         {
00324                 objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
00325                 // *FIX: shouldn't we just keep the child?
00326                 if (objectp)
00327                 {
00328                         LLViewerObject* parentp = objectp->getSubParent();
00329 
00330                         if (parentp)
00331                         {
00332                                 root_objectp = parentp;
00333                         }
00334                         else
00335                         {
00336                                 root_objectp = objectp;
00337                         }
00338                 }
00339         }
00340 
00341         LLVOVolume *volobjp = NULL;
00342         if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
00343         {
00344                 volobjp = (LLVOVolume *)objectp;
00345         }
00346 
00347         if( !objectp )
00348         {
00349                 //forfeit focus
00350                 if (gFocusMgr.childHasKeyboardFocus(this))
00351                 {
00352                         gFocusMgr.setKeyboardFocus(NULL);
00353                 }
00354 
00355                 // Disable all text input fields
00356                 clearCtrls();
00357                 return;
00358         }
00359 
00360         // can move or rotate only linked group with move permissions, or sub-object with move and modify perms
00361         BOOL enable_move        = objectp->permMove() && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
00362         BOOL enable_scale       = objectp->permMove() && objectp->permModify();
00363         BOOL enable_rotate      = objectp->permMove() && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
00364 
00365         LLVector3 vec;
00366         if (enable_move)
00367         {
00368                 vec = objectp->getPositionEdit();
00369                 mCtrlPosX->set( vec.mV[VX] );
00370                 mCtrlPosY->set( vec.mV[VY] );
00371                 mCtrlPosZ->set( vec.mV[VZ] );
00372         }
00373         else
00374         {
00375                 mCtrlPosX->clear();
00376                 mCtrlPosY->clear();
00377                 mCtrlPosZ->clear();
00378         }
00379 
00380 
00381         mLabelPosition->setEnabled( enable_move );
00382         mCtrlPosX->setEnabled(enable_move);
00383         mCtrlPosY->setEnabled(enable_move);
00384         mCtrlPosZ->setEnabled(enable_move);
00385 
00386         if (enable_scale)
00387         {
00388                 vec = objectp->getScale();
00389                 mCtrlScaleX->set( vec.mV[VX] );
00390                 mCtrlScaleY->set( vec.mV[VY] );
00391                 mCtrlScaleZ->set( vec.mV[VZ] );
00392         }
00393         else
00394         {
00395                 mCtrlScaleX->clear();
00396                 mCtrlScaleY->clear();
00397                 mCtrlScaleZ->clear();
00398         }
00399 
00400         mLabelSize->setEnabled( enable_scale );
00401         mCtrlScaleX->setEnabled( enable_scale );
00402         mCtrlScaleY->setEnabled( enable_scale );
00403         mCtrlScaleZ->setEnabled( enable_scale );
00404 
00405         LLQuaternion object_rot = objectp->getRotationEdit();
00406         object_rot.getEulerAngles(&(mCurEulerDegrees.mV[VX]), &(mCurEulerDegrees.mV[VY]), &(mCurEulerDegrees.mV[VZ]));
00407         mCurEulerDegrees *= RAD_TO_DEG;
00408         mCurEulerDegrees.mV[VX] = fmod(llround(mCurEulerDegrees.mV[VX], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
00409         mCurEulerDegrees.mV[VY] = fmod(llround(mCurEulerDegrees.mV[VY], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
00410         mCurEulerDegrees.mV[VZ] = fmod(llround(mCurEulerDegrees.mV[VZ], OBJECT_ROTATION_PRECISION) + 360.f, 360.f);
00411 
00412         if (enable_rotate)
00413         {
00414                 mCtrlRotX->set( mCurEulerDegrees.mV[VX] );
00415                 mCtrlRotY->set( mCurEulerDegrees.mV[VY] );
00416                 mCtrlRotZ->set( mCurEulerDegrees.mV[VZ] );
00417         }
00418         else
00419         {
00420                 mCtrlRotX->clear();
00421                 mCtrlRotY->clear();
00422                 mCtrlRotZ->clear();
00423         }
00424 
00425         mLabelRotation->setEnabled( enable_rotate );
00426         mCtrlRotX->setEnabled( enable_rotate );
00427         mCtrlRotY->setEnabled( enable_rotate );
00428         mCtrlRotZ->setEnabled( enable_rotate );
00429 
00430         BOOL owners_identical;
00431         LLUUID owner_id;
00432         LLString owner_name;
00433         owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
00434 
00435         // BUG? Check for all objects being editable?
00436         S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
00437         BOOL editable = root_objectp->permModify();
00438         S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
00439         BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
00440                                                  && (selected_count == 1);
00441 
00442         // Select Single Message
00443         childSetVisible("select_single", FALSE);
00444         childSetVisible("edit_object", FALSE);
00445         if (!editable || single_volume || selected_count <= 1)
00446         {
00447                 childSetVisible("edit_object", TRUE);
00448                 childSetEnabled("edit_object", TRUE);
00449         }
00450         else
00451         {
00452                 childSetVisible("select_single", TRUE);
00453                 childSetEnabled("select_single", TRUE);
00454         }
00455         // Lock checkbox - only modifiable if you own the object.
00456         BOOL self_owned = (gAgent.getID() == owner_id);
00457         mCheckLock->setEnabled( roots_selected > 0 && self_owned );
00458 
00459         // More lock and debit checkbox - get the values
00460         BOOL valid;
00461         U32 owner_mask_on;
00462         U32 owner_mask_off;
00463         valid = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER, &owner_mask_on, &owner_mask_off);
00464 
00465         if(valid)
00466         {
00467                 if(owner_mask_on & PERM_MOVE)
00468                 {
00469                         // owner can move, so not locked
00470                         mCheckLock->set(FALSE);
00471                         mCheckLock->setTentative(FALSE);
00472                 }
00473                 else if(owner_mask_off & PERM_MOVE)
00474                 {
00475                         // owner can't move, so locked
00476                         mCheckLock->set(TRUE);
00477                         mCheckLock->setTentative(FALSE);
00478                 }
00479                 else
00480                 {
00481                         // some locked, some not locked
00482                         mCheckLock->set(FALSE);
00483                         mCheckLock->setTentative(TRUE);
00484                 }
00485         }
00486 
00487         BOOL is_flexible = volobjp && volobjp->isFlexible();
00488 
00489         // Physics checkbox
00490         mIsPhysical = root_objectp->usePhysics();
00491         mCheckPhysics->set( mIsPhysical );
00492         mCheckPhysics->setEnabled( roots_selected>0 
00493                                                                 && (editable || gAgent.isGodlike()) 
00494                                                                 && !is_flexible);
00495 
00496         mIsTemporary = root_objectp->flagTemporaryOnRez();
00497         mCheckTemporary->set( mIsTemporary );
00498         mCheckTemporary->setEnabled( roots_selected>0 && editable );
00499 
00500         mIsPhantom = root_objectp->flagPhantom();
00501         mCheckPhantom->set( mIsPhantom );
00502         mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible );
00503 
00504 #if 0 // 1.9.2
00505         mCastShadows = root_objectp->flagCastShadows();
00506         mCheckCastShadows->set( mCastShadows );
00507         mCheckCastShadows->setEnabled( roots_selected==1 && editable );
00508 #endif
00509         
00510         // Update material part
00511         // slightly inefficient - materials are unique per object, not per TE
00512         U8 material_code = 0;
00513         struct f : public LLSelectedTEGetFunctor<U8>
00514         {
00515                 U8 get(LLViewerObject* object, S32 te)
00516                 {
00517                         return object->getMaterial();
00518                 }
00519         } func;
00520         bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code );
00521         
00522         if (editable && single_volume && material_same)
00523         {
00524                 mComboMaterial->setEnabled( TRUE );
00525                 mLabelMaterial->setEnabled( TRUE );
00526                 if (material_code == LL_MCODE_LIGHT)
00527                 {
00528                         if (mComboMaterial->getItemCount() == mComboMaterialItemCount)
00529                         {
00530                                 mComboMaterial->add(LEGACY_FULLBRIGHT_DESC);
00531                         }
00532                         mComboMaterial->setSimple(LEGACY_FULLBRIGHT_DESC);
00533                 }
00534                 else
00535                 {
00536                         if (mComboMaterial->getItemCount() != mComboMaterialItemCount)
00537                         {
00538                                 mComboMaterial->remove(LEGACY_FULLBRIGHT_DESC);
00539                         }
00540                         // *TODO:Translate
00541                         mComboMaterial->setSimple(LLString(LLMaterialTable::basic.getName(material_code)));
00542                 }
00543         }
00544         else
00545         {
00546                 mComboMaterial->setEnabled( FALSE );
00547                 mLabelMaterial->setEnabled( FALSE );    
00548         }
00549         //----------------------------------------------------------------------------
00550 
00551         S32 selected_item       = MI_BOX;
00552         S32     selected_hole   = MI_HOLE_SAME;
00553         BOOL enabled = FALSE;
00554         BOOL hole_enabled = FALSE;
00555         F32 scale_x=1.f, scale_y=1.f;
00556         
00557         if( !objectp || !objectp->getVolume() || !editable || !single_volume)
00558         {
00559                 // Clear out all geometry fields.
00560                 mComboBaseType->clear();
00561                 mSpinHollow->clear();
00562                 mSpinCutBegin->clear();
00563                 mSpinCutEnd->clear();
00564                 mCtrlPathBegin->clear();
00565                 mCtrlPathEnd->clear();
00566                 mSpinScaleX->clear();
00567                 mSpinScaleY->clear();
00568                 mSpinTwist->clear();
00569                 mSpinTwistBegin->clear();
00570                 mComboHoleType->clear();
00571                 mSpinShearX->clear();
00572                 mSpinShearY->clear();
00573                 mSpinTaperX->clear();
00574                 mSpinTaperY->clear();
00575                 mSpinRadiusOffset->clear();
00576                 mSpinRevolutions->clear();
00577                 mSpinSkew->clear();
00578                 
00579                 mSelectedType = MI_NONE;
00580         }
00581         else
00582         {
00583                 // Only allowed to change these parameters for objects
00584                 // that you have permissions on AND are not attachments.
00585                 enabled = root_objectp->permModify();
00586 
00587                 const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
00588 
00589                 // Volume type
00590                 U8 path = volume_params.getPathParams().getCurveType();
00591                 U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
00592                 U8 profile      = profile_and_hole & LL_PCODE_PROFILE_MASK;
00593                 U8 hole         = profile_and_hole & LL_PCODE_HOLE_MASK;
00594                 
00595                 // Scale goes first so we can differentiate between a sphere and a torus,
00596                 // which have the same profile and path types.
00597 
00598                 // Scale
00599                 scale_x = volume_params.getRatioX();
00600                 scale_y = volume_params.getRatioY();
00601 
00602                 BOOL linear_path = (path == LL_PCODE_PATH_LINE) || (path == LL_PCODE_PATH_FLEXIBLE);
00603                 if ( linear_path && profile == LL_PCODE_PROFILE_CIRCLE )
00604                 {
00605                         selected_item = MI_CYLINDER;
00606                 }
00607                 else if ( linear_path && profile == LL_PCODE_PROFILE_SQUARE )
00608                 {
00609                         selected_item = MI_BOX;
00610                 }
00611                 else if ( linear_path && profile == LL_PCODE_PROFILE_ISOTRI )
00612                 {
00613                         selected_item = MI_PRISM;
00614                 }
00615                 else if ( linear_path && profile == LL_PCODE_PROFILE_EQUALTRI )
00616                 {
00617                         selected_item = MI_PRISM;
00618                 }
00619                 else if ( linear_path && profile == LL_PCODE_PROFILE_RIGHTTRI )
00620                 {
00621                         selected_item = MI_PRISM;
00622                 }
00623                 else if (path == LL_PCODE_PATH_FLEXIBLE) // shouldn't happen
00624                 {
00625                         selected_item = MI_CYLINDER; // reasonable default
00626                 }
00627                 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y > 0.75f)
00628                 {
00629                         selected_item = MI_SPHERE;
00630                 }
00631                 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE && scale_y <= 0.75f)
00632                 {
00633                         selected_item = MI_TORUS;
00634                 }
00635                 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_CIRCLE_HALF)
00636                 {
00637                         selected_item = MI_SPHERE;
00638                 }
00639                 else if ( path == LL_PCODE_PATH_CIRCLE2 && profile == LL_PCODE_PROFILE_CIRCLE )
00640                 {
00641                         // Spirals aren't supported.  Make it into a sphere.  JC
00642                         selected_item = MI_SPHERE;
00643                 }
00644                 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_EQUALTRI )
00645                 {
00646                         selected_item = MI_RING;
00647                 }
00648                 else if ( path == LL_PCODE_PATH_CIRCLE && profile == LL_PCODE_PROFILE_SQUARE && scale_y <= 0.75f)
00649                 {
00650                         selected_item = MI_TUBE;
00651                 }
00652                 else
00653                 {
00654                         llinfos << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << llendl;
00655                         selected_item = MI_BOX;
00656                 }
00657 
00658 
00659                 if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
00660                 {
00661                         selected_item = MI_SCULPT;
00662                         LLFirstUse::useSculptedPrim();
00663                 }
00664 
00665                 
00666                 mComboBaseType  ->setCurrentByIndex( selected_item );
00667                 mSelectedType = selected_item;
00668                 
00669                 // Grab S path
00670                 F32 begin_s     = volume_params.getBeginS();
00671                 F32 end_s       = volume_params.getEndS();
00672 
00673                 // Compute cut and advanced cut from S and T
00674                 F32 begin_t = volume_params.getBeginT();
00675                 F32 end_t       = volume_params.getEndT();
00676 
00677                 // Hollowness
00678                 F32 hollow = volume_params.getHollow();
00679                 mSpinHollow->set( 100.f * hollow );
00680 
00681                 // All hollow objects allow a shape to be selected.
00682                 if (hollow > 0.f)
00683                 {
00684                         switch (hole)
00685                         {
00686                         case LL_PCODE_HOLE_CIRCLE:
00687                                 selected_hole = MI_HOLE_CIRCLE;
00688                                 break;
00689                         case LL_PCODE_HOLE_SQUARE:
00690                                 selected_hole = MI_HOLE_SQUARE;
00691                                 break;
00692                         case LL_PCODE_HOLE_TRIANGLE:
00693                                 selected_hole = MI_HOLE_TRIANGLE;
00694                                 break;
00695                         case LL_PCODE_HOLE_SAME:
00696                         default:
00697                                 selected_hole = MI_HOLE_SAME;
00698                                 break;
00699                         }
00700                         mComboHoleType->setCurrentByIndex( selected_hole );
00701                         hole_enabled = enabled;
00702                 }
00703                 else
00704                 {
00705                         mComboHoleType->setCurrentByIndex( MI_HOLE_SAME );
00706                         hole_enabled = FALSE;
00707                 }
00708 
00709                 // Cut interpretation varies based on base object type
00710                 F32 cut_begin, cut_end, adv_cut_begin, adv_cut_end;
00711 
00712                 if ( selected_item == MI_SPHERE || selected_item == MI_TORUS || 
00713                          selected_item == MI_TUBE   || selected_item == MI_RING )
00714                 {
00715                         cut_begin               = begin_t;
00716                         cut_end                 = end_t;
00717                         adv_cut_begin   = begin_s;
00718                         adv_cut_end             = end_s;
00719                 }
00720                 else
00721                 {
00722                         cut_begin       = begin_s;
00723                         cut_end         = end_s;
00724                         adv_cut_begin   = begin_t;
00725                         adv_cut_end     = end_t;
00726                 }
00727 
00728                 mSpinCutBegin   ->set( cut_begin );
00729                 mSpinCutEnd             ->set( cut_end );
00730                 mCtrlPathBegin  ->set( adv_cut_begin );
00731                 mCtrlPathEnd    ->set( adv_cut_end );
00732 
00733                 // Twist
00734                 F32 twist               = volume_params.getTwist();
00735                 F32 twist_begin = volume_params.getTwistBegin();
00736                 // Check the path type for conversion.
00737                 if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
00738                 {
00739                         twist           *= OBJECT_TWIST_LINEAR_MAX;
00740                         twist_begin     *= OBJECT_TWIST_LINEAR_MAX;
00741                 }
00742                 else
00743                 {
00744                         twist           *= OBJECT_TWIST_MAX;
00745                         twist_begin     *= OBJECT_TWIST_MAX;
00746                 }
00747 
00748                 mSpinTwist              ->set( twist );
00749                 mSpinTwistBegin ->set( twist_begin );
00750 
00751                 // Shear
00752                 F32 shear_x = volume_params.getShearX();
00753                 F32 shear_y = volume_params.getShearY();
00754                 mSpinShearX->set( shear_x );
00755                 mSpinShearY->set( shear_y );
00756 
00757                 // Taper
00758                 F32 taper_x     = volume_params.getTaperX();
00759                 F32 taper_y = volume_params.getTaperY();
00760                 mSpinTaperX->set( taper_x );
00761                 mSpinTaperY->set( taper_y );
00762 
00763                 // Radius offset.
00764                 F32 radius_offset = volume_params.getRadiusOffset();
00765                 // Limit radius offset, based on taper and hole size y.
00766                 F32 radius_mag = fabs(radius_offset);
00767                 F32 hole_y_mag = fabs(scale_y);
00768                 F32 taper_y_mag  = fabs(taper_y);
00769                 // Check to see if the taper effects us.
00770                 if ( (radius_offset > 0.f && taper_y < 0.f) ||
00771                          (radius_offset < 0.f && taper_y > 0.f) )
00772                 {
00773                         // The taper does not help increase the radius offset range.
00774                         taper_y_mag = 0.f;
00775                 }
00776                 F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
00777                 // Enforce the maximum magnitude.
00778                 if (radius_mag > max_radius_mag)
00779                 {
00780                         // Check radius offset sign.
00781                         if (radius_offset < 0.f)
00782                         {
00783                                 radius_offset = -max_radius_mag;
00784                         }
00785                         else
00786                         {
00787                                 radius_offset = max_radius_mag;
00788                         }
00789                 }
00790                 mSpinRadiusOffset->set( radius_offset);
00791 
00792                 // Revolutions
00793                 F32 revolutions = volume_params.getRevolutions();
00794                 mSpinRevolutions->set( revolutions );
00795                 
00796                 // Skew
00797                 F32 skew        = volume_params.getSkew();
00798                 // Limit skew, based on revolutions hole size x.
00799                 F32 skew_mag= fabs(skew);
00800                 F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
00801                 // Discontinuity; A revolution of 1 allows skews below 0.5.
00802                 if ( fabs(revolutions - 1.0f) < 0.001)
00803                         min_skew_mag = 0.0f;
00804 
00805                 // Clip skew.
00806                 if (skew_mag < min_skew_mag)
00807                 {
00808                         // Check skew sign.
00809                         if (skew < 0.0f)
00810                         {
00811                                 skew = -min_skew_mag;
00812                         }
00813                         else 
00814                         {
00815                                 skew = min_skew_mag;
00816                         }
00817                 }
00818                 mSpinSkew->set( skew );
00819         }
00820 
00821         // Compute control visibility, label names, and twist range.
00822         // Start with defaults.
00823         BOOL cut_visible                = TRUE;
00824         BOOL hollow_visible             = TRUE;
00825         BOOL top_size_x_visible                 = TRUE;
00826         BOOL top_size_y_visible                 = TRUE;
00827         BOOL top_shear_x_visible                = TRUE;
00828         BOOL top_shear_y_visible                = TRUE;
00829         BOOL twist_visible                              = TRUE;
00830         BOOL advanced_cut_visible               = FALSE;
00831         BOOL taper_visible                              = FALSE;
00832         BOOL skew_visible                               = FALSE;
00833         BOOL radius_offset_visible              = FALSE;
00834         BOOL revolutions_visible                = FALSE;
00835         BOOL sculpt_texture_visible     = FALSE;
00836         F32      twist_min                                      = OBJECT_TWIST_LINEAR_MIN;
00837         F32      twist_max                                      = OBJECT_TWIST_LINEAR_MAX;
00838         F32      twist_inc                                      = OBJECT_TWIST_LINEAR_INC;
00839 
00840         BOOL advanced_is_dimple = FALSE;
00841         BOOL size_is_hole = FALSE;
00842 
00843         // Tune based on overall volume type
00844         switch (selected_item)
00845         {
00846         case MI_SPHERE:
00847                 top_size_x_visible              = FALSE;
00848                 top_size_y_visible              = FALSE;
00849                 top_shear_x_visible             = FALSE;
00850                 top_shear_y_visible             = FALSE;
00851                 //twist_visible                 = FALSE;
00852                 advanced_cut_visible    = TRUE;
00853                 advanced_is_dimple              = TRUE;
00854                 twist_min                               = OBJECT_TWIST_MIN;
00855                 twist_max                               = OBJECT_TWIST_MAX;
00856                 twist_inc                               = OBJECT_TWIST_INC;
00857                 break;
00858 
00859         case MI_TORUS:
00860         case MI_TUBE:   
00861         case MI_RING:
00862                 //top_size_x_visible            = FALSE;
00863                 //top_size_y_visible            = FALSE;
00864                 size_is_hole                    = TRUE;
00865                 skew_visible                    = TRUE;
00866                 advanced_cut_visible    = TRUE;
00867                 taper_visible                   = TRUE;
00868                 radius_offset_visible   = TRUE;
00869                 revolutions_visible             = TRUE;
00870                 twist_min                               = OBJECT_TWIST_MIN;
00871                 twist_max                               = OBJECT_TWIST_MAX;
00872                 twist_inc                               = OBJECT_TWIST_INC;
00873 
00874                 break;
00875 
00876         case MI_SCULPT:
00877                 cut_visible             = FALSE;
00878                 hollow_visible          = FALSE;
00879                 twist_visible           = FALSE;
00880                 top_size_x_visible      = FALSE;
00881                 top_size_y_visible      = FALSE;
00882                 top_shear_x_visible     = FALSE;
00883                 top_shear_y_visible     = FALSE;
00884                 skew_visible            = FALSE;
00885                 advanced_cut_visible    = FALSE;
00886                 taper_visible           = FALSE;
00887                 radius_offset_visible   = FALSE;
00888                 revolutions_visible     = FALSE;
00889                 sculpt_texture_visible  = TRUE;
00890 
00891                 break;
00892                 
00893         case MI_BOX:
00894         case MI_CYLINDER:
00895         case MI_PRISM:
00896         default:
00897                 break;
00898         }
00899 
00900         // Check if we need to change top size/hole size params.
00901         switch (selected_item)
00902         {
00903         case MI_SPHERE:
00904         case MI_TORUS:
00905         case MI_TUBE:
00906         case MI_RING:
00907                 mSpinScaleX->set( scale_x );
00908                 mSpinScaleY->set( scale_y );
00909                 mSpinScaleX->setMinValue(OBJECT_MIN_HOLE_SIZE);
00910                 mSpinScaleX->setMaxValue(OBJECT_MAX_HOLE_SIZE_X);
00911                 mSpinScaleY->setMinValue(OBJECT_MIN_HOLE_SIZE);
00912                 mSpinScaleY->setMaxValue(OBJECT_MAX_HOLE_SIZE_Y);
00913                 break;
00914         default:
00915                 if (editable)
00916                 {
00917                         mSpinScaleX->set( 1.f - scale_x );
00918                         mSpinScaleY->set( 1.f - scale_y );
00919                         mSpinScaleX->setMinValue(-1.f);
00920                         mSpinScaleX->setMaxValue(1.f);
00921                         mSpinScaleY->setMinValue(-1.f);
00922                         mSpinScaleY->setMaxValue(1.f);
00923                 }
00924                 break;
00925         }
00926 
00927         // Check if we need to limit the hollow based on the hole type.
00928         if (  selected_hole == MI_HOLE_SQUARE && 
00929                   ( selected_item == MI_CYLINDER || selected_item == MI_TORUS ||
00930                     selected_item == MI_PRISM    || selected_item == MI_RING  ||
00931                         selected_item == MI_SPHERE ) )
00932         {
00933                 mSpinHollow->setMinValue(0.f);
00934                 mSpinHollow->setMaxValue(70.f);
00935         }
00936         else 
00937         {
00938                 mSpinHollow->setMinValue(0.f);
00939                 mSpinHollow->setMaxValue(95.f);
00940         }
00941 
00942         // Update field enablement
00943         mLabelBaseType  ->setEnabled( enabled );
00944         mComboBaseType  ->setEnabled( enabled );
00945 
00946         mLabelCut               ->setEnabled( enabled );
00947         mSpinCutBegin   ->setEnabled( enabled );
00948         mSpinCutEnd             ->setEnabled( enabled );
00949 
00950         mLabelHollow    ->setEnabled( enabled );
00951         mSpinHollow             ->setEnabled( enabled );
00952         mLabelHoleType  ->setEnabled( hole_enabled );
00953         mComboHoleType  ->setEnabled( hole_enabled );
00954 
00955         mLabelTwist             ->setEnabled( enabled );
00956         mSpinTwist              ->setEnabled( enabled );
00957         mSpinTwistBegin ->setEnabled( enabled );
00958 
00959         mLabelSkew              ->setEnabled( enabled );
00960         mSpinSkew               ->setEnabled( enabled );
00961 
00962         childSetVisible("scale_hole", FALSE);
00963         childSetVisible("scale_taper", FALSE);
00964         if (top_size_x_visible || top_size_y_visible)
00965         {
00966                 if (size_is_hole)
00967                 {
00968                         childSetVisible("scale_hole", TRUE);
00969                         childSetEnabled("scale_hole", enabled);
00970                 }
00971                 else
00972                 {
00973                         childSetVisible("scale_taper", TRUE);
00974                         childSetEnabled("scale_taper", enabled);
00975                 }
00976         }
00977         
00978         mSpinScaleX             ->setEnabled( enabled );
00979         mSpinScaleY             ->setEnabled( enabled );
00980 
00981         mLabelShear             ->setEnabled( enabled );
00982         mSpinShearX             ->setEnabled( enabled );
00983         mSpinShearY             ->setEnabled( enabled );
00984 
00985         childSetVisible("advanced_cut", FALSE);
00986         childSetVisible("advanced_dimple", FALSE);
00987         if (advanced_cut_visible)
00988         {
00989                 if (advanced_is_dimple)
00990                 {
00991                         childSetVisible("advanced_dimple", TRUE);
00992                         childSetEnabled("advanced_dimple", enabled);
00993                 }
00994                 else
00995                 {
00996                         childSetVisible("advanced_cut", TRUE);
00997                         childSetEnabled("advanced_cut", enabled);
00998                 }
00999         }
01000         
01001         mCtrlPathBegin  ->setEnabled( enabled );
01002         mCtrlPathEnd    ->setEnabled( enabled );
01003 
01004         mLabelTaper             ->setEnabled( enabled );
01005         mSpinTaperX             ->setEnabled( enabled );
01006         mSpinTaperY             ->setEnabled( enabled );
01007 
01008         mLabelRadiusOffset->setEnabled( enabled );
01009         mSpinRadiusOffset ->setEnabled( enabled );
01010 
01011         mLabelRevolutions->setEnabled( enabled );
01012         mSpinRevolutions ->setEnabled( enabled );
01013 
01014         // Update field visibility
01015         mLabelCut               ->setVisible( cut_visible );
01016         mSpinCutBegin   ->setVisible( cut_visible );
01017         mSpinCutEnd             ->setVisible( cut_visible ); 
01018 
01019         mLabelHollow    ->setVisible( hollow_visible );
01020         mSpinHollow             ->setVisible( hollow_visible );
01021         mLabelHoleType  ->setVisible( hollow_visible );
01022         mComboHoleType  ->setVisible( hollow_visible );
01023         
01024         mLabelTwist             ->setVisible( twist_visible );
01025         mSpinTwist              ->setVisible( twist_visible );
01026         mSpinTwistBegin ->setVisible( twist_visible );
01027         mSpinTwist              ->setMinValue(  twist_min );
01028         mSpinTwist              ->setMaxValue(  twist_max );
01029         mSpinTwist              ->setIncrement( twist_inc );
01030         mSpinTwistBegin ->setMinValue(  twist_min );
01031         mSpinTwistBegin ->setMaxValue(  twist_max );
01032         mSpinTwistBegin ->setIncrement( twist_inc );
01033 
01034         mSpinScaleX             ->setVisible( top_size_x_visible );
01035         mSpinScaleY             ->setVisible( top_size_y_visible );
01036 
01037         mLabelSkew              ->setVisible( skew_visible );
01038         mSpinSkew               ->setVisible( skew_visible );
01039 
01040         mLabelShear             ->setVisible( top_shear_x_visible || top_shear_y_visible );
01041         mSpinShearX             ->setVisible( top_shear_x_visible );
01042         mSpinShearY             ->setVisible( top_shear_y_visible );
01043 
01044         mCtrlPathBegin  ->setVisible( advanced_cut_visible );
01045         mCtrlPathEnd    ->setVisible( advanced_cut_visible );
01046 
01047         mLabelTaper             ->setVisible( taper_visible );
01048         mSpinTaperX             ->setVisible( taper_visible );
01049         mSpinTaperY             ->setVisible( taper_visible );
01050 
01051         mLabelRadiusOffset->setVisible( radius_offset_visible );
01052         mSpinRadiusOffset ->setVisible( radius_offset_visible );
01053 
01054         mLabelRevolutions->setVisible( revolutions_visible );
01055         mSpinRevolutions ->setVisible( revolutions_visible );
01056 
01057         mCtrlSculptTexture->setVisible(sculpt_texture_visible);
01058         mLabelSculptType->setVisible(sculpt_texture_visible);
01059         mCtrlSculptType->setVisible(sculpt_texture_visible);
01060 
01061 
01062         // sculpt texture
01063 
01064         if (selected_item == MI_SCULPT)
01065         {
01066         LLUUID id;
01067                 LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
01068 
01069                 
01070                 if (sculpt_params) // if we have a legal sculpt param block for this object:
01071                 {
01072                         if (mObject != objectp)  // we've just selected a new object, so save for undo
01073                         {
01074                                 mSculptTextureRevert = sculpt_params->getSculptTexture();
01075                                 mSculptTypeRevert    = sculpt_params->getSculptType();
01076                         }
01077                 
01078                         LLTextureCtrl*  mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control");
01079                         if(mTextureCtrl)
01080                         {
01081                                 mTextureCtrl->setTentative(FALSE);
01082                                 mTextureCtrl->setEnabled(editable);
01083                                 if (editable)
01084                                         mTextureCtrl->setImageAssetID(sculpt_params->getSculptTexture());
01085                                 else
01086                                         mTextureCtrl->setImageAssetID(LLUUID::null);
01087                         }
01088 
01089                         if (mCtrlSculptType)
01090                         {
01091                                 mCtrlSculptType->setCurrentByIndex(sculpt_params->getSculptType());
01092                                 mCtrlSculptType->setEnabled(editable);
01093                         }
01094 
01095                         if (mLabelSculptType)
01096                         {
01097                                 mLabelSculptType->setEnabled(TRUE);
01098                         }
01099                 }
01100         }
01101         else
01102         {
01103                 mSculptTextureRevert = LLUUID::null;
01104         }
01105 
01106         
01107         //----------------------------------------------------------------------------
01108 
01109         mObject = objectp;
01110         mRootObject = root_objectp;
01111 }
01112 
01113 // static
01114 BOOL LLPanelObject::precommitValidate( LLUICtrl* ctrl, void* userdata )
01115 {
01116         // TODO: Richard will fill this in later.  
01117         return TRUE; // FALSE means that validation failed and new value should not be commited.
01118 }
01119 
01120 void LLPanelObject::sendIsPhysical()
01121 {
01122         BOOL value = mCheckPhysics->get();
01123         if( mIsPhysical != value )
01124         {
01125                 LLSelectMgr::getInstance()->selectionUpdatePhysics(value);
01126                 mIsPhysical = value;
01127 
01128                 llinfos << "update physics sent" << llendl;
01129         }
01130         else
01131         {
01132                 llinfos << "update physics not changed" << llendl;
01133         }
01134 }
01135 
01136 void LLPanelObject::sendIsTemporary()
01137 {
01138         BOOL value = mCheckTemporary->get();
01139         if( mIsTemporary != value )
01140         {
01141                 LLSelectMgr::getInstance()->selectionUpdateTemporary(value);
01142                 mIsTemporary = value;
01143 
01144                 llinfos << "update temporary sent" << llendl;
01145         }
01146         else
01147         {
01148                 llinfos << "update temporary not changed" << llendl;
01149         }
01150 }
01151 
01152 
01153 void LLPanelObject::sendIsPhantom()
01154 {
01155         BOOL value = mCheckPhantom->get();
01156         if( mIsPhantom != value )
01157         {
01158                 LLSelectMgr::getInstance()->selectionUpdatePhantom(value);
01159                 mIsPhantom = value;
01160 
01161                 llinfos << "update phantom sent" << llendl;
01162         }
01163         else
01164         {
01165                 llinfos << "update phantom not changed" << llendl;
01166         }
01167 }
01168 
01169 void LLPanelObject::sendCastShadows()
01170 {
01171         BOOL value = mCheckCastShadows->get();
01172         if( mCastShadows != value )
01173         {
01174                 LLSelectMgr::getInstance()->selectionUpdateCastShadows(value);
01175                 mCastShadows = value;
01176 
01177                 llinfos << "update cast shadows sent" << llendl;
01178         }
01179         else
01180         {
01181                 llinfos << "update cast shadows not changed" << llendl;
01182         }
01183 }
01184 
01185 // static
01186 void LLPanelObject::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
01187 {
01188         //LLPanelObject* self = (LLPanelObject*) userdata;
01189         LLComboBox* box = (LLComboBox*) ctrl;
01190 
01191         if (box)
01192         {
01193                 // apply the currently selected material to the object
01194                 const LLString& material_name = box->getSimple();
01195                 if (material_name != LEGACY_FULLBRIGHT_DESC)
01196                 {
01197                         U8 material_code = LLMaterialTable::basic.getMCode(material_name.c_str());
01198                         LLSelectMgr::getInstance()->selectionSetMaterial(material_code);
01199                 }
01200         }
01201 }
01202 
01203 // static
01204 void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
01205 {
01206         LLPanelObject* self = (LLPanelObject*) userdata;
01207 
01208         if (self->mObject.isNull())
01209         {
01210                 return;
01211         }
01212 
01213         if (self->mObject->getPCode() != LL_PCODE_VOLUME)
01214         {
01215                 // Don't allow modification of non-volume objects.
01216                 return;
01217         }
01218 
01219         LLVolume *volume = self->mObject->getVolume();
01220         if (!volume)
01221         {
01222                 return;
01223         }
01224 
01225         LLVolumeParams volume_params;
01226         self->getVolumeParams(volume_params);
01227         
01228 
01229         
01230         // set sculpting
01231         S32 selected_type = self->mComboBaseType->getCurrentIndex();
01232 
01233         if (selected_type == MI_SCULPT)
01234         {
01235                 self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, TRUE);
01236                 LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
01237                 if (sculpt_params)
01238                         volume_params.setSculptID(sculpt_params->getSculptTexture(), sculpt_params->getSculptType());
01239         }
01240         else
01241         {
01242                 LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
01243                 if (sculpt_params)
01244                         self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
01245         }
01246 
01247         // Update the volume, if necessary.
01248         self->mObject->updateVolume(volume_params);
01249 
01250 
01251         // This was added to make sure thate when changes are made, the UI
01252         // adjusts to present valid options.
01253         // *FIX: only some changes, ie, hollow or primitive type changes,
01254         // require a refresh.
01255         self->refresh();
01256 
01257 }
01258 
01259 void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
01260 {
01261         // Figure out what type of volume to make
01262         S32 was_selected_type = mSelectedType;
01263         S32 selected_type = mComboBaseType->getCurrentIndex();
01264         U8 profile;
01265         U8 path;
01266         switch ( selected_type )
01267         {
01268         case MI_CYLINDER:
01269                 profile = LL_PCODE_PROFILE_CIRCLE;
01270                 path = LL_PCODE_PATH_LINE;
01271                 break;
01272 
01273         case MI_BOX:
01274                 profile = LL_PCODE_PROFILE_SQUARE;
01275                 path = LL_PCODE_PATH_LINE;
01276                 break;
01277 
01278         case MI_PRISM:
01279                 profile = LL_PCODE_PROFILE_EQUALTRI;
01280                 path = LL_PCODE_PATH_LINE;
01281                 break;
01282 
01283         case MI_SPHERE:
01284                 profile = LL_PCODE_PROFILE_CIRCLE_HALF;
01285                 path = LL_PCODE_PATH_CIRCLE;
01286                 break;
01287 
01288         case MI_TORUS:
01289                 profile = LL_PCODE_PROFILE_CIRCLE;
01290                 path = LL_PCODE_PATH_CIRCLE;
01291                 break;
01292 
01293         case MI_TUBE:
01294                 profile = LL_PCODE_PROFILE_SQUARE;
01295                 path = LL_PCODE_PATH_CIRCLE;
01296                 break;
01297 
01298         case MI_RING:
01299                 profile = LL_PCODE_PROFILE_EQUALTRI;
01300                 path = LL_PCODE_PATH_CIRCLE;
01301                 break;
01302 
01303         case MI_SCULPT:
01304                 profile = LL_PCODE_PROFILE_CIRCLE;
01305                 path = LL_PCODE_PATH_CIRCLE;
01306                 break;
01307                 
01308         default:
01309                 llwarns << "Unknown base type " << selected_type 
01310                         << " in getVolumeParams()" << llendl;
01311                 // assume a box
01312                 selected_type = MI_BOX;
01313                 profile = LL_PCODE_PROFILE_SQUARE;
01314                 path = LL_PCODE_PATH_LINE;
01315                 break;
01316         }
01317 
01318 
01319         if (path == LL_PCODE_PATH_LINE)
01320         {
01321                 LLVOVolume *volobjp = (LLVOVolume *)(LLViewerObject*)(mObject);
01322                 if (volobjp->isFlexible())
01323                 {
01324                         path = LL_PCODE_PATH_FLEXIBLE;
01325                 }
01326         }
01327         
01328         S32 selected_hole = mComboHoleType->getCurrentIndex();
01329         U8 hole;
01330         switch (selected_hole)
01331         {
01332         case MI_HOLE_CIRCLE: 
01333                 hole = LL_PCODE_HOLE_CIRCLE;
01334                 break;
01335         case MI_HOLE_SQUARE:
01336                 hole = LL_PCODE_HOLE_SQUARE;
01337                 break;
01338         case MI_HOLE_TRIANGLE:
01339                 hole = LL_PCODE_HOLE_TRIANGLE;
01340                 break;
01341         case MI_HOLE_SAME:
01342         default:
01343                 hole = LL_PCODE_HOLE_SAME;
01344                 break;
01345         }
01346 
01347         volume_params.setType(profile | hole, path);
01348         mSelectedType = selected_type;
01349         
01350         // Compute cut start/end
01351         F32 cut_begin   = mSpinCutBegin->get();
01352         F32 cut_end             = mSpinCutEnd->get();
01353 
01354         // Make sure at least OBJECT_CUT_INC of the object survives
01355         if (cut_begin > cut_end - OBJECT_MIN_CUT_INC)
01356         {
01357                 cut_begin = cut_end - OBJECT_MIN_CUT_INC;
01358                 mSpinCutBegin->set(cut_begin);
01359         }
01360 
01361         F32 adv_cut_begin       = mCtrlPathBegin->get();
01362         F32 adv_cut_end         = mCtrlPathEnd->get();
01363 
01364         // Make sure at least OBJECT_CUT_INC of the object survives
01365         if (adv_cut_begin > adv_cut_end - OBJECT_MIN_CUT_INC)
01366         {
01367                 adv_cut_begin = adv_cut_end - OBJECT_MIN_CUT_INC;
01368                 mCtrlPathBegin->set(adv_cut_begin);
01369         }
01370 
01371         F32 begin_s, end_s;
01372         F32 begin_t, end_t;
01373 
01374         if (selected_type == MI_SPHERE || selected_type == MI_TORUS || 
01375                 selected_type == MI_TUBE   || selected_type == MI_RING)
01376         {
01377                 begin_s = adv_cut_begin;
01378                 end_s   = adv_cut_end;
01379 
01380                 begin_t = cut_begin;
01381                 end_t   = cut_end;
01382         }
01383         else
01384         {
01385                 begin_s = cut_begin;
01386                 end_s   = cut_end;
01387 
01388                 begin_t = adv_cut_begin;
01389                 end_t   = adv_cut_end;
01390         }
01391 
01392         volume_params.setBeginAndEndS(begin_s, end_s);
01393         volume_params.setBeginAndEndT(begin_t, end_t);
01394 
01395         // Hollowness
01396         F32 hollow = mSpinHollow->get() / 100.f;
01397 
01398         if (  selected_hole == MI_HOLE_SQUARE && 
01399                 ( selected_type == MI_CYLINDER || selected_type == MI_TORUS ||
01400                   selected_type == MI_PRISM    || selected_type == MI_RING  ||
01401                   selected_type == MI_SPHERE ) )
01402         {
01403                 if (hollow > 0.7f) hollow = 0.7f;
01404         }
01405 
01406         volume_params.setHollow( hollow );
01407 
01408         // Twist Begin,End
01409         F32 twist_begin = mSpinTwistBegin->get();
01410         F32 twist               = mSpinTwist->get();
01411         // Check the path type for twist conversion.
01412         if (path == LL_PCODE_PATH_LINE || path == LL_PCODE_PATH_FLEXIBLE)
01413         {
01414                 twist_begin     /= OBJECT_TWIST_LINEAR_MAX;
01415                 twist           /= OBJECT_TWIST_LINEAR_MAX;
01416         }
01417         else
01418         {
01419                 twist_begin     /= OBJECT_TWIST_MAX;
01420                 twist           /= OBJECT_TWIST_MAX;
01421         }
01422 
01423         volume_params.setTwistBegin(twist_begin);
01424         volume_params.setTwist(twist);
01425 
01426         // Scale X,Y
01427         F32 scale_x = mSpinScaleX->get();
01428         F32 scale_y = mSpinScaleY->get();
01429         if ( was_selected_type == MI_BOX || was_selected_type == MI_CYLINDER || was_selected_type == MI_PRISM)
01430         {
01431                 scale_x = 1.f - scale_x;
01432                 scale_y = 1.f - scale_y;
01433         }
01434         
01435         // Skew
01436         F32 skew = mSpinSkew->get();
01437 
01438         // Taper X,Y
01439         F32 taper_x = mSpinTaperX->get();
01440         F32 taper_y = mSpinTaperY->get();
01441 
01442         // Radius offset
01443         F32 radius_offset = mSpinRadiusOffset->get();
01444 
01445         // Revolutions
01446         F32 revolutions   = mSpinRevolutions->get();
01447 
01448         if ( selected_type == MI_SPHERE )
01449         {
01450                 // Snap values to valid sphere parameters.
01451                 scale_x                 = 1.0f;
01452                 scale_y                 = 1.0f;
01453                 skew                    = 0.0f;
01454                 taper_x                 = 0.0f;
01455                 taper_y                 = 0.0f;
01456                 radius_offset   = 0.0f;
01457                 revolutions             = 1.0f;
01458         }
01459         else if ( selected_type == MI_TORUS || selected_type == MI_TUBE ||
01460                           selected_type == MI_RING )
01461         {
01462                 scale_x = llclamp(
01463                         scale_x,
01464                         OBJECT_MIN_HOLE_SIZE,
01465                         OBJECT_MAX_HOLE_SIZE_X);
01466                 scale_y = llclamp(
01467                         scale_y,
01468                         OBJECT_MIN_HOLE_SIZE,
01469                         OBJECT_MAX_HOLE_SIZE_Y);
01470 
01471                 // Limit radius offset, based on taper and hole size y.
01472                 F32 radius_mag = fabs(radius_offset);
01473                 F32 hole_y_mag = fabs(scale_y);
01474                 F32 taper_y_mag  = fabs(taper_y);
01475                 // Check to see if the taper effects us.
01476                 if ( (radius_offset > 0.f && taper_y < 0.f) ||
01477                          (radius_offset < 0.f && taper_y > 0.f) )
01478                 {
01479                         // The taper does not help increase the radius offset range.
01480                         taper_y_mag = 0.f;
01481                 }
01482                 F32 max_radius_mag = 1.f - hole_y_mag * (1.f - taper_y_mag) / (1.f - hole_y_mag);
01483                 // Enforce the maximum magnitude.
01484                 if (radius_mag > max_radius_mag)
01485                 {
01486                         // Check radius offset sign.
01487                         if (radius_offset < 0.f)
01488                         {
01489                                 radius_offset = -max_radius_mag;
01490                         }
01491                         else
01492                         {
01493                                 radius_offset = max_radius_mag;
01494                         }
01495                 }
01496                         
01497                 // Check the skew value against the revolutions.
01498                 F32 skew_mag= fabs(skew);
01499                 F32 min_skew_mag = 1.0f - 1.0f / (revolutions * scale_x + 1.0f);
01500                 // Discontinuity; A revolution of 1 allows skews below 0.5.
01501                 if ( fabs(revolutions - 1.0f) < 0.001)
01502                         min_skew_mag = 0.0f;
01503 
01504                 // Clip skew.
01505                 if (skew_mag < min_skew_mag)
01506                 {
01507                         // Check skew sign.
01508                         if (skew < 0.0f)
01509                         {
01510                                 skew = -min_skew_mag;
01511                         }
01512                         else 
01513                         {
01514                                 skew = min_skew_mag;
01515                         }
01516                 }
01517         }
01518 
01519         volume_params.setRatio( scale_x, scale_y );
01520         volume_params.setSkew(skew);
01521         volume_params.setTaper( taper_x, taper_y );
01522         volume_params.setRadiusOffset(radius_offset);
01523         volume_params.setRevolutions(revolutions);
01524 
01525         // Shear X,Y
01526         F32 shear_x = mSpinShearX->get();
01527         F32 shear_y = mSpinShearY->get();
01528         volume_params.setShear( shear_x, shear_y );
01529 
01530         if (selected_type == MI_SCULPT)
01531         {
01532                 volume_params.setSculptID(LLUUID::null, 0);
01533                 volume_params.setBeginAndEndT   (0, 1);
01534                 volume_params.setBeginAndEndS   (0, 1);
01535                 volume_params.setHollow         (0);
01536                 volume_params.setTwistBegin     (0);
01537                 volume_params.setTwistEnd       (0);
01538                 volume_params.setRatio          (1, 0.5);
01539                 volume_params.setShear          (0, 0);
01540                 volume_params.setTaper          (0, 0);
01541                 volume_params.setRevolutions    (1);
01542                 volume_params.setRadiusOffset   (0);
01543                 volume_params.setSkew           (0);
01544         }
01545 
01546 }
01547 
01548 // BUG: Make work with multiple objects
01549 void LLPanelObject::sendRotation()
01550 {
01551         if (mObject.isNull()) return;
01552 
01553         LLVector3 new_rot(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
01554         new_rot.mV[VX] = llround(new_rot.mV[VX], OBJECT_ROTATION_PRECISION);
01555         new_rot.mV[VY] = llround(new_rot.mV[VY], OBJECT_ROTATION_PRECISION);
01556         new_rot.mV[VZ] = llround(new_rot.mV[VZ], OBJECT_ROTATION_PRECISION);
01557 
01558         // Note: must compare before conversion to radians
01559         LLVector3 delta = new_rot - mCurEulerDegrees;
01560 
01561         if (delta.magVec() >= 0.0005f)
01562         {
01563                 mCurEulerDegrees = new_rot;
01564                 new_rot *= DEG_TO_RAD;
01565 
01566                 LLQuaternion rotation;
01567                 rotation.setQuat(new_rot.mV[VX], new_rot.mV[VY], new_rot.mV[VZ]);
01568 
01569                 if (mRootObject != mObject)
01570                 {
01571                         rotation = rotation * ~mRootObject->getRotationRegion();
01572                 }
01573 
01574                 mObject->setRotation(rotation, TRUE );
01575 
01576                 LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_ROTATION);
01577         }
01578 }
01579 
01580 
01581 // BUG: Make work with multiple objects
01582 void LLPanelObject::sendScale()
01583 {
01584         if (mObject.isNull()) return;
01585 
01586         LLVector3 newscale(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
01587 
01588         LLVector3 delta = newscale - mObject->getScale();
01589         if (delta.magVec() >= 0.0005f)
01590         {
01591                 // scale changed by more than 1/2 millimeter
01592 
01593                 // check to see if we aren't scaling the textures
01594                 // (in which case the tex coord's need to be recomputed)
01595                 BOOL dont_stretch_textures = !LLManipScale::getStretchTextures();
01596                 if (dont_stretch_textures)
01597                 {
01598                         LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_SCALE);
01599                 }
01600 
01601                 mObject->setScale(newscale, TRUE);
01602                 LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE | UPD_POSITION);
01603 
01604                 LLSelectMgr::getInstance()->adjustTexturesByScale(TRUE, !dont_stretch_textures);
01605 //              llinfos << "scale sent" << llendl;
01606         }
01607         else
01608         {
01609 //              llinfos << "scale not changed" << llendl;
01610         }
01611 }
01612 
01613 
01614 void LLPanelObject::sendPosition()
01615 {       
01616         if (mObject.isNull()) return;
01617 
01618         LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
01619         LLViewerRegion* regionp = mObject->getRegion();
01620                 
01621         // Clamp the Z height
01622         const F32 height = newpos.mV[VZ];
01623         const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject);
01624         const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
01625 
01626         if (!mObject->isAttachment())
01627         {
01628                 if ( height < min_height)
01629                 {
01630                         newpos.mV[VZ] = min_height;
01631                         mCtrlPosZ->set( min_height );
01632                 }
01633                 else if ( height > max_height )
01634                 {
01635                         newpos.mV[VZ] = max_height;
01636                         mCtrlPosZ->set( max_height );
01637                 }
01638 
01639                 // Grass is always drawn on the ground, so clamp its position to the ground
01640                 if (mObject->getPCode() == LL_PCODE_LEGACY_GRASS)
01641                 {
01642                         mCtrlPosZ->set(LLWorld::getInstance()->resolveLandHeightAgent(newpos) + 1.f);
01643                 }
01644         }
01645 
01646         // Make sure new position is in a valid region, so the object
01647         // won't get dumped by the simulator.
01648         LLVector3d new_pos_global = regionp->getPosGlobalFromRegion(newpos);
01649 
01650         if ( LLWorld::getInstance()->positionRegionValidGlobal(new_pos_global) )
01651         {
01652                 // send only if the position is changed, that is, the delta vector is not zero
01653                 LLVector3d old_pos_global = mObject->getPositionGlobal();
01654                 LLVector3d delta = new_pos_global - old_pos_global;
01655                 // moved more than 1/2 millimeter
01656                 if (delta.magVec() >= 0.0005f)
01657                 {
01658                         if (mRootObject != mObject)
01659                         {
01660                                 newpos = newpos - mRootObject->getPositionRegion();
01661                                 newpos = newpos * ~mRootObject->getRotationRegion();
01662                                 mObject->setPositionParent(newpos);
01663                         }
01664                         else
01665                         {
01666                                 mObject->setPositionEdit(newpos);
01667                         }
01668                         LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
01669 
01670                         LLSelectMgr::getInstance()->updateSelectionCenter();
01671                 }
01672         }
01673         else
01674         {
01675                 // move failed, so we update the UI with the correct values
01676                 LLVector3 vec = mRootObject->getPositionRegion();
01677                 mCtrlPosX->set(vec.mV[VX]);
01678                 mCtrlPosY->set(vec.mV[VY]);
01679                 mCtrlPosZ->set(vec.mV[VZ]);
01680         }
01681 }
01682 
01683 void LLPanelObject::sendSculpt()
01684 {
01685         if (mObject.isNull())
01686                 return;
01687         
01688         LLSculptParams sculpt_params;
01689 
01690         if (mCtrlSculptTexture)
01691                 sculpt_params.setSculptTexture(mCtrlSculptTexture->getImageAssetID());
01692 
01693         if (mCtrlSculptType)
01694                 sculpt_params.setSculptType(mCtrlSculptType->getCurrentIndex());
01695         
01696         mObject->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
01697 }
01698 
01699 void LLPanelObject::refresh()
01700 {
01701         getState();
01702         if (mObject.notNull() && mObject->isDead())
01703         {
01704                 mObject = NULL;
01705         }
01706 
01707         if (mRootObject.notNull() && mRootObject->isDead())
01708         {
01709                 mRootObject = NULL;
01710         }
01711 }
01712 
01713 
01714 void LLPanelObject::draw()
01715 {
01716         const LLColor4  white(  1.0f,   1.0f,   1.0f,   1);
01717         const LLColor4  red(    1.0f,   0.25f,  0.f,    1);
01718         const LLColor4  green(  0.f,    1.0f,   0.f,    1);
01719         const LLColor4  blue(   0.f,    0.5f,   1.0f,   1);
01720 
01721         // Tune the colors of the labels
01722         LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
01723 
01724         if (tool == LLToolCompTranslate::getInstance())
01725         {
01726                 mCtrlPosX       ->setLabelColor(red);
01727                 mCtrlPosY       ->setLabelColor(green);
01728                 mCtrlPosZ       ->setLabelColor(blue);
01729 
01730                 mCtrlScaleX     ->setLabelColor(white);
01731                 mCtrlScaleY     ->setLabelColor(white);
01732                 mCtrlScaleZ     ->setLabelColor(white);
01733 
01734                 mCtrlRotX       ->setLabelColor(white);
01735                 mCtrlRotY       ->setLabelColor(white);
01736                 mCtrlRotZ       ->setLabelColor(white);
01737         }
01738         else if ( tool == LLToolCompScale::getInstance() )
01739         {
01740                 mCtrlPosX       ->setLabelColor(white);
01741                 mCtrlPosY       ->setLabelColor(white);
01742                 mCtrlPosZ       ->setLabelColor(white);
01743 
01744                 mCtrlScaleX     ->setLabelColor(red);
01745                 mCtrlScaleY     ->setLabelColor(green);
01746                 mCtrlScaleZ     ->setLabelColor(blue);
01747 
01748                 mCtrlRotX       ->setLabelColor(white);
01749                 mCtrlRotY       ->setLabelColor(white);
01750                 mCtrlRotZ       ->setLabelColor(white);
01751         }
01752         else if ( tool == LLToolCompRotate::getInstance() )
01753         {
01754                 mCtrlPosX       ->setLabelColor(white);
01755                 mCtrlPosY       ->setLabelColor(white);
01756                 mCtrlPosZ       ->setLabelColor(white);
01757 
01758                 mCtrlScaleX     ->setLabelColor(white);
01759                 mCtrlScaleY     ->setLabelColor(white);
01760                 mCtrlScaleZ     ->setLabelColor(white);
01761 
01762                 mCtrlRotX       ->setLabelColor(red);
01763                 mCtrlRotY       ->setLabelColor(green);
01764                 mCtrlRotZ       ->setLabelColor(blue);
01765         }
01766         else
01767         {
01768                 mCtrlPosX       ->setLabelColor(white);
01769                 mCtrlPosY       ->setLabelColor(white);
01770                 mCtrlPosZ       ->setLabelColor(white);
01771 
01772                 mCtrlScaleX     ->setLabelColor(white);
01773                 mCtrlScaleY     ->setLabelColor(white);
01774                 mCtrlScaleZ     ->setLabelColor(white);
01775 
01776                 mCtrlRotX       ->setLabelColor(white);
01777                 mCtrlRotY       ->setLabelColor(white);
01778                 mCtrlRotZ       ->setLabelColor(white);
01779         }
01780 
01781         LLPanel::draw();
01782 }
01783 
01784 // virtual
01785 void LLPanelObject::clearCtrls()
01786 {
01787         LLPanel::clearCtrls();
01788 
01789         mCheckLock              ->set(FALSE);
01790         mCheckLock              ->setEnabled( FALSE );
01791         mCheckPhysics   ->set(FALSE);
01792         mCheckPhysics   ->setEnabled( FALSE );
01793         mCheckTemporary ->set(FALSE);
01794         mCheckTemporary ->setEnabled( FALSE );
01795         mCheckPhantom   ->set(FALSE);
01796         mCheckPhantom   ->setEnabled( FALSE );
01797 #if 0 // 1.9.2
01798         mCheckCastShadows->set(FALSE);
01799         mCheckCastShadows->setEnabled( FALSE );
01800 #endif
01801         mComboMaterial  ->setEnabled( FALSE );
01802         mLabelMaterial  ->setEnabled( FALSE );
01803         // Disable text labels
01804         mLabelPosition  ->setEnabled( FALSE );
01805         mLabelSize              ->setEnabled( FALSE );
01806         mLabelRotation  ->setEnabled( FALSE );
01807         mLabelBaseType  ->setEnabled( FALSE );
01808         mLabelCut               ->setEnabled( FALSE );
01809         mLabelHollow    ->setEnabled( FALSE );
01810         mLabelHoleType  ->setEnabled( FALSE );
01811         mLabelTwist             ->setEnabled( FALSE );
01812         mLabelSkew              ->setEnabled( FALSE );
01813         mLabelShear             ->setEnabled( FALSE );
01814         mLabelTaper             ->setEnabled( FALSE );
01815         mLabelRadiusOffset->setEnabled( FALSE );
01816         mLabelRevolutions->setEnabled( FALSE );
01817 
01818         childSetVisible("select_single", FALSE);
01819         childSetVisible("edit_object", TRUE);   
01820         childSetEnabled("edit_object", FALSE);
01821         
01822         childSetEnabled("scale_hole", FALSE);
01823         childSetEnabled("scale_taper", FALSE);
01824         childSetEnabled( "advanced_cut", FALSE );
01825         childSetEnabled( "advanced_dimple", FALSE );
01826 }
01827 
01828 //
01829 // Static functions
01830 //
01831 
01832 // static
01833 void LLPanelObject::onCommitLock(LLUICtrl *ctrl, void *data)
01834 {
01835         // Checkbox will have toggled itself
01836         LLPanelObject *self = (LLPanelObject *)data;
01837 
01838         if(self->mRootObject.isNull()) return;
01839 
01840         BOOL new_state = self->mCheckLock->get();
01841         
01842         LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, !new_state, PERM_MOVE | PERM_MODIFY);
01843 }
01844 
01845 // static
01846 void LLPanelObject::onCommitPosition( LLUICtrl* ctrl, void* userdata )
01847 {
01848         LLPanelObject* self = (LLPanelObject*) userdata;
01849         self->sendPosition();
01850 }
01851 
01852 // static
01853 void LLPanelObject::onCommitScale( LLUICtrl* ctrl, void* userdata )
01854 {
01855         LLPanelObject* self = (LLPanelObject*) userdata;
01856         self->sendScale();
01857 }
01858 
01859 // static
01860 void LLPanelObject::onCommitRotation( LLUICtrl* ctrl, void* userdata )
01861 {
01862         LLPanelObject* self = (LLPanelObject*) userdata;
01863         self->sendRotation();
01864 }
01865 
01866 // static
01867 void LLPanelObject::onCommitPhysics( LLUICtrl* ctrl, void* userdata )
01868 {
01869         LLPanelObject* self = (LLPanelObject*) userdata;
01870         self->sendIsPhysical();
01871 }
01872 
01873 // static
01874 void LLPanelObject::onCommitTemporary( LLUICtrl* ctrl, void* userdata )
01875 {
01876         LLPanelObject* self = (LLPanelObject*) userdata;
01877         self->sendIsTemporary();
01878 }
01879 
01880 // static
01881 void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata )
01882 {
01883         LLPanelObject* self = (LLPanelObject*) userdata;
01884         self->sendIsPhantom();
01885 }
01886 
01887 // static
01888 void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
01889 {
01890         LLPanelObject* self = (LLPanelObject*) userdata;
01891         self->sendCastShadows();
01892 }
01893 
01894 
01895 // static
01896 void LLPanelObject::onSelectSculpt(LLUICtrl* ctrl, void* userdata)
01897 {
01898         LLPanelObject* self = (LLPanelObject*) userdata;
01899 
01900     LLTextureCtrl* mTextureCtrl = self->getChild<LLTextureCtrl>("sculpt texture control");
01901 
01902         if (mTextureCtrl)
01903         {
01904                 self->mSculptTextureRevert = mTextureCtrl->getImageAssetID();
01905         }
01906         
01907         self->sendSculpt();
01908 }
01909 
01910 
01911 void LLPanelObject::onCommitSculpt( LLUICtrl* ctrl, void* userdata )
01912 {
01913         LLPanelObject* self = (LLPanelObject*) userdata;
01914 
01915         self->sendSculpt();
01916 }
01917 
01918 // static
01919 BOOL LLPanelObject::onDropSculpt(LLUICtrl*, LLInventoryItem* item, void* userdata)
01920 {
01921         LLPanelObject* self = (LLPanelObject*) userdata;
01922 
01923     LLTextureCtrl* mTextureCtrl = self->getChild<LLTextureCtrl>("sculpt texture control");
01924 
01925         if (mTextureCtrl)
01926         {
01927                 LLUUID asset = item->getAssetUUID();
01928 
01929                 mTextureCtrl->setImageAssetID(asset);
01930                 self->mSculptTextureRevert = asset;
01931         }
01932 
01933         return TRUE;
01934 }
01935 
01936 
01937 // static
01938 void LLPanelObject::onCancelSculpt(LLUICtrl* ctrl, void* userdata)
01939 {
01940         LLPanelObject* self = (LLPanelObject*) userdata;
01941 
01942         LLTextureCtrl* mTextureCtrl = self->getChild<LLTextureCtrl>("sculpt texture control");
01943         if(!mTextureCtrl)
01944                 return;
01945         
01946         mTextureCtrl->setImageAssetID(self->mSculptTextureRevert);
01947         
01948         self->sendSculpt();
01949 }
01950 
01951 // static
01952 void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
01953 {
01954         LLPanelObject* self = (LLPanelObject*) userdata;
01955 
01956         self->sendSculpt();
01957 }

Generated on Fri May 16 08:33:55 2008 for SecondLife by  doxygen 1.5.5