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

Generated on Thu Jul 1 06:08:59 2010 for Second Life Viewer by  doxygen 1.4.7