00001 00032 // file include 00033 #include "llviewerprecompiledheaders.h" 00034 00035 /* 00036 #include "llpanelmorph.h" 00037 00038 // library includes 00039 #include "llerror.h" 00040 #include "llrect.h" 00041 #include "llstring.h" 00042 #include "llfontgl.h" 00043 00044 // project includes 00045 #include "llui.h" 00046 #include "llspinctrl.h" 00047 #include "llcheckboxctrl.h" 00048 #include "lltextbox.h" 00049 #include "llbutton.h" 00050 //#include "lldraghandle.h" 00051 00052 #include "llviewerwindow.h" 00053 #include "llviewerobject.h" 00054 #include "llresmgr.h" 00055 00056 #include "llcontrol.h" 00057 00058 #include "llagent.h" 00059 #include "llvoavatar.h" 00060 #include "lltoolmgr.h" 00061 #include "lltoolmorph.h" 00062 #include "llquantize.h" 00063 00064 // 00065 // Constants 00066 // 00067 const S32 VPAD = 2; 00068 const S32 HPAD = 4; 00069 00070 const S32 TITLE_WIDTH = 100; 00071 const S32 TITLE_HEIGHT = 16; 00072 00073 const S32 CLOSE_BOX_SIZE = 16; 00074 00075 const S32 LABEL_HOFF = 8; 00076 const S32 LABEL_WIDTH = 140; 00077 const S32 SPIN_WIDTH = 250; 00078 00079 // minimum and maximum morph weight values (a UI/network constraint, not inherent to morphs) 00080 const F32 MORPH_WEIGHT_MIN = (-1.f); 00081 const F32 MORPH_WEIGHT_MAX = (1.f); 00082 // this is the magic number that morph values are quantized to for network transmission purposes 00083 // the 200 value is a result of encoding the weights as a string (and avoiding NULL terminators 00084 // and avoiding \n (the between-NV-pair delimiter). Map -1 to 1 to 50-250. HACK. JC 00085 const S32 MORPH_WEIGHT_OFFSET = (50); 00086 const S32 MORPH_WEIGHT_QUANTUM = ((MORPH_WEIGHT_MAX - MORPH_WEIGHT_MIN) / MAXSTRINGVAL); 00087 00088 //#define MORPH_PANEL_SHOW_SPINNERS 00089 00090 // 00091 // Globals 00092 // 00093 LLPanelMorph *gPanelMorph = NULL; 00094 00095 // 00096 // Methods 00097 // 00098 00099 //static 00100 //----------------------------------------------------------------------------- 00101 // LLPanelMorph() 00102 //----------------------------------------------------------------------------- 00103 LLPanelMorph::LLPanelMorph(const std::string& name, const LLRect& rect) 00104 : LLPanel( name, rect ) 00105 { 00106 mParamSpinners = NULL; 00107 mSexRadioGroup = NULL; 00108 mRect = rect; 00109 mMesh = NULL; 00110 setBackgroundVisible( TRUE ); 00111 } 00112 00113 //----------------------------------------------------------------------------- 00114 // ~LLPanelMorph() 00115 //----------------------------------------------------------------------------- 00116 LLPanelMorph::~LLPanelMorph() 00117 { 00118 #ifdef MORPH_PANEL_SHOW_SPINNERS 00119 for (S32 i = 0; i < mNumParamSpinners; i++) 00120 { 00121 removeChild(mParamSpinners[i]); 00122 delete mParamSpinners[i]; 00123 } 00124 delete [] mParamSpinners; 00125 #endif 00126 } 00127 00128 // static 00129 //----------------------------------------------------------------------------- 00130 // onCommitSexChange() 00131 //----------------------------------------------------------------------------- 00132 void LLPanelMorph::onCommitSexChange( void *data) 00133 { 00134 // LLRadioGroup *group = (LLRadioGroup *)data; 00135 00136 // LLVOAvatar *avatarp = gAgent.getAvatarObject(); 00137 // 00138 // LLNameValue* avatarSexNV = avatarp->getNVPair("AvatarSex"); 00139 // if (!avatarSexNV) 00140 // { 00141 // avatarp->addNVPair( "AvatarSex U32 READ_WRITE SIM_SPACE_VIEWER 0"); 00142 // avatarSexNV = avatarp->getNVPair("AvatarSex"); 00143 // } 00144 // 00145 // avatarSexNV->setU32(gSavedSettings.getU32("AvatarSex")); 00146 // 00147 // avatarp->sendNVPairToSimulator("AvatarSex"); 00148 // 00149 // // preemptively update sex based on local value 00150 // avatarp->updateSex(); 00151 // 00152 // LLVisualParamHint::requestHintUpdates(); 00153 00154 } 00155 00156 00157 // static 00158 //----------------------------------------------------------------------------- 00159 // onCommitMorphChange() 00160 //----------------------------------------------------------------------------- 00161 void LLPanelMorph::onCommitMorphChange( LLUICtrl* ctrl, void* userdata ) 00162 { 00163 //#ifdef MORPH_PANEL_SHOW_SPINNERS 00164 // LLVOAvatar *avatarp = gAgent.getAvatarObject(); 00165 // 00166 // LLPanelMorph* self = (LLPanelMorph*) userdata; 00167 // 00168 // S32 i = 0; 00169 // for(LLPolyMorphTarget* morphTargetp = self->mMesh->getFirstVisualParam(); 00170 // morphTargetp; 00171 // morphTargetp = self->mMesh->getNextVisualParam()) 00172 // { 00173 // for(S32 j = 0; j < self->mNumParamSpinners; j++) 00174 // { 00175 // if (!strcmp(self->mParamSpinners[j]->getName(), morphTargetp->getName())) 00176 // { 00177 // avatarp->mHeadMesh0.getMesh()->setDistortionWeight(morphTargetp, self->mParamSpinners[j]->get()); 00178 // } 00179 // } 00180 // i++; 00181 // } 00182 // avatarp->updateDistortions(); 00183 // avatarp->sendVisualParams(); 00184 //#endif 00185 } 00186 00187 //----------------------------------------------------------------------------- 00188 // updateSpinners() 00189 //----------------------------------------------------------------------------- 00190 void LLPanelMorph::updateSpinners(LLPolyMesh *mesh) 00191 { 00192 if (mesh != mMesh) return; 00193 #ifdef MORPH_PANEL_SHOW_SPINNERS 00194 00195 for(LLViewerVisualParam *param = (LLViewerVisualParam*)gAgent.getAvatarObject()->getFirstVisualParam(); 00196 param; 00197 param = gAgent.getAvatarObject()->getNextVisualParam()) 00198 { 00199 if (param->getID() == -1 || 00200 param->getGroup() != LLVisualParam::VISUAL_PARAM_GROUP_TWEAKABLE) continue; 00201 00202 F32 paramWeight = gAgent.getAvatarObject()->getVisualParamWeight(morphTargetp); 00203 00204 for (S32 i = 0; i < mNumParamSpinners; i++) 00205 { 00206 if (!strcmp(mParamSpinners[i]->getName() , morphTargetp->getName())) 00207 { 00208 mParamSpinners[i]->set(paramWeight); 00209 } 00210 } 00211 } 00212 #endif 00213 } 00214 00215 //----------------------------------------------------------------------------- 00216 // createSpinners() 00217 //----------------------------------------------------------------------------- 00218 void LLPanelMorph::createSpinners(LLPolyMesh *mesh) 00219 { 00220 const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); 00221 S32 cur_y; 00222 S32 new_height; 00223 S32 control_focus = -1; 00224 00225 if (mSexRadioGroup) 00226 { 00227 removeChild(mSexRadioGroup); 00228 delete mSexRadioGroup; 00229 } 00230 00231 if (mParamSpinners) 00232 { 00233 for (S32 i = 0; i < mNumParamSpinners; i++) 00234 { 00235 if (mParamSpinners[i]->hasFocus()) 00236 { 00237 control_focus = i; 00238 mParamSpinners[i]->setFocus(FALSE); 00239 } 00240 } 00241 for (i = 0; i < mNumParamSpinners; i++) 00242 { 00243 removeChild(mParamSpinners[i]); 00244 delete mParamSpinners[i]; 00245 } 00246 delete [] mParamSpinners; 00247 mParamSpinners = NULL; 00248 } 00249 00250 #ifdef MORPH_PANEL_SHOW_SPINNERS 00251 S32 numSpinners = 0; 00252 00253 for(LLViewerVisualParam *param = (LLViewerVisualParam*)gAgent.getAvatarObject()->getFirstVisualParam(); 00254 param; 00255 param = gAgent.getAvatarObject()->getNextVisualParam()) 00256 { 00257 if(param->getID() != -1 && 00258 param->getGroup() == LLVisualParam::VISUAL_PARAM_GROUP_TWEAKABLE) 00259 { 00260 numSpinners++; 00261 } 00262 } 00263 00264 if (numSpinners != 0) 00265 { 00266 mParamSpinners = new LLSpinCtrl*[numSpinners]; 00267 } 00268 00269 // set focus back to control #n 00270 if (control_focus >= 0 && control_focus < numSpinners) 00271 { 00272 mParamSpinners[control_focus]->setFocus(TRUE); 00273 } 00274 new_height = numSpinners * (SPINCTRL_HEIGHT + VPAD) + (VPAD * 3) + CHECKBOXCTRL_HEIGHT + VPAD + VPAD; 00275 00276 #else 00277 new_height = (VPAD * 3) + CHECKBOXCTRL_HEIGHT + VPAD + VPAD; 00278 #endif 00279 00280 LLRect panelRect = getRect(); 00281 reshape(panelRect.getWidth(), new_height, TRUE); 00282 00283 cur_y = new_height - VPAD - VPAD; 00284 00285 LLRect radio_rect; 00286 radio_rect.setLeftTopAndSize(HPAD + LABEL_HOFF, 00287 cur_y, 00288 getRect().getWidth() - HPAD - HPAD - LABEL_HOFF, 00289 CHECKBOXCTRL_HEIGHT + VPAD); 00290 mSexRadioGroup = new LLRadioGroup("sex radio", 00291 radio_rect, 00292 "AvatarSex", 00293 &LLPanelMorph::onCommitSexChange, 00294 (void *)this); 00295 addChild(mSexRadioGroup); 00296 00297 radio_rect.setLeftTopAndSize(HPAD + LABEL_HOFF, 00298 0, 00299 (getRect().getWidth() - HPAD - HPAD - LABEL_HOFF) / 2.f, 00300 0); 00301 mSexRadioGroup->addRadioButton("Female", "Female", radio_rect, font); 00302 00303 radio_rect.setLeftTopAndSize(((getRect().getWidth() - HPAD - HPAD - LABEL_HOFF) / 2.f) + HPAD + LABEL_HOFF, 00304 0, 00305 (getRect().getWidth() - HPAD - HPAD - LABEL_HOFF) / 2.f, 00306 0); 00307 mSexRadioGroup->addRadioButton("Male", "Male", radio_rect, font); 00308 00309 cur_y -= CHECKBOXCTRL_HEIGHT + VPAD + VPAD; 00310 00311 #ifdef MORPH_PANEL_SHOW_SPINNERS 00312 S32 i = 0; 00313 00314 for(LLViewerVisualParam *param = (LLViewerVisualParam*)gAgent.getAvatarObject()->getFirstVisualParam(); 00315 param; 00316 param = gAgent.getAvatarObject()->getNextVisualParam()) 00317 { 00318 if (param->getID() == -1 || 00319 param->getGroup() != LLVisualParam::VISUAL_PARAM_GROUP_TWEAKABLE) continue; 00320 LLRect spinnerRect; 00321 spinnerRect.setLeftTopAndSize(HPAD + LABEL_HOFF, 00322 cur_y, 00323 getRect().getWidth() - HPAD - HPAD - LABEL_HOFF, 00324 cur_y - SPINCTRL_HEIGHT); 00325 mParamSpinners[i] = new LLSpinCtrl(param->getName(), 00326 spinnerRect, 00327 font, 00328 param->getName(), 00329 &LLPanelMorph::onCommitMorphChange, 00330 this, 00331 param->getWeight(), 00332 param->getMinWeight(), 00333 param->getMaxWeight(), 00334 MORPH_WEIGHT_QUANTUM * 2, 00335 NULL, 00336 LABEL_WIDTH ); 00337 00338 mParamSpinners[i]->setPrecision(2); 00339 mParamSpinners[i]->setFollowsTop(); 00340 mParamSpinners[i]->setFollowsLeft(); 00341 addChild(mParamSpinners[i]); 00342 cur_y -= VPAD + SPINCTRL_HEIGHT; 00343 i++; 00344 } 00345 00346 mNumParamSpinners = numSpinners; 00347 #endif 00348 mMesh = mesh; 00349 } 00350 */