PageRenderTime 115ms CodeModel.GetById 24ms app.highlight 82ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llpanelface.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1185 lines | 958 code | 137 blank | 90 comment | 109 complexity | 00f6f95ef9d4afb77952c9bb250e70b8 MD5 | raw file
   1/** 
   2 * @file llpanelface.cpp
   3 * @brief Panel in the tools floater for editing face textures, colors, etc.
   4 *
   5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "llviewerprecompiledheaders.h"
  28
  29// file include
  30#include "llpanelface.h"
  31 
  32// library includes
  33#include "llcalc.h"
  34#include "llerror.h"
  35#include "llfocusmgr.h"
  36#include "llrect.h"
  37#include "llstring.h"
  38#include "llfontgl.h"
  39
  40// project includes
  41#include "llbutton.h"
  42#include "llcheckboxctrl.h"
  43#include "llcolorswatch.h"
  44#include "llcombobox.h"
  45#include "lldrawpoolbump.h"
  46#include "llface.h"
  47#include "lllineeditor.h"
  48#include "llmediaentry.h"
  49#include "llresmgr.h"
  50#include "llselectmgr.h"
  51#include "llspinctrl.h"
  52#include "lltextbox.h"
  53#include "lltexturectrl.h"
  54#include "lltextureentry.h"
  55#include "lltooldraganddrop.h"
  56#include "llui.h"
  57#include "llviewercontrol.h"
  58#include "llviewermedia.h"
  59#include "llviewerobject.h"
  60#include "llviewerstats.h"
  61#include "llvovolume.h"
  62#include "lluictrlfactory.h"
  63#include "llpluginclassmedia.h"
  64#include "llviewertexturelist.h"
  65
  66//
  67// Methods
  68//
  69
  70BOOL	LLPanelFace::postBuild()
  71{
  72	childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
  73	childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
  74	childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
  75	childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
  76	childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
  77	childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
  78	childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
  79	childSetAction("button apply",&LLPanelFace::onClickApply,this);
  80	childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this);
  81	childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
  82	childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
  83	childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
  84
  85	LLRect	rect = this->getRect();
  86	LLTextureCtrl*	mTextureCtrl;
  87	LLColorSwatchCtrl*	mColorSwatch;
  88
  89	LLComboBox*		mComboTexGen;
  90
  91	LLCheckBoxCtrl	*mCheckFullbright;
  92	
  93	LLTextBox*		mLabelColorTransp;
  94	LLSpinCtrl*		mCtrlColorTransp;		// transparency = 1 - alpha
  95
  96	LLSpinCtrl*     mCtrlGlow;
  97
  98	setMouseOpaque(FALSE);
  99	mTextureCtrl = getChild<LLTextureCtrl>("texture control");
 100	if(mTextureCtrl)
 101	{
 102		mTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" )));
 103		mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
 104		mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
 105		mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
 106		mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
 107		mTextureCtrl->setFollowsTop();
 108		mTextureCtrl->setFollowsLeft();
 109		// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
 110		mTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
 111		// Allow any texture to be used during non-immediate mode.
 112		mTextureCtrl->setNonImmediateFilterPermMask(PERM_NONE);
 113		LLAggregatePermissions texture_perms;
 114		if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
 115		{
 116			BOOL can_copy = 
 117				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || 
 118				texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
 119			BOOL can_transfer = 
 120				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || 
 121				texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
 122			mTextureCtrl->setCanApplyImmediately(can_copy && can_transfer);
 123		}
 124		else
 125		{
 126			mTextureCtrl->setCanApplyImmediately(FALSE);
 127		}
 128	}
 129
 130	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
 131	if(mColorSwatch)
 132	{
 133		mColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitColor, this, _2));
 134		mColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelColor, this, _2));
 135		mColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectColor, this, _2));
 136		mColorSwatch->setFollowsTop();
 137		mColorSwatch->setFollowsLeft();
 138		mColorSwatch->setCanApplyImmediately(TRUE);
 139	}
 140
 141	mLabelColorTransp = getChild<LLTextBox>("color trans");
 142	if(mLabelColorTransp)
 143	{
 144		mLabelColorTransp->setFollowsTop();
 145		mLabelColorTransp->setFollowsLeft();
 146	}
 147
 148	mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
 149	if(mCtrlColorTransp)
 150	{
 151		mCtrlColorTransp->setCommitCallback(boost::bind(&LLPanelFace::onCommitAlpha, this, _2));
 152		mCtrlColorTransp->setPrecision(0);
 153		mCtrlColorTransp->setFollowsTop();
 154		mCtrlColorTransp->setFollowsLeft();
 155	}
 156
 157	mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
 158	if (mCheckFullbright)
 159	{
 160		mCheckFullbright->setCommitCallback(LLPanelFace::onCommitFullbright, this);
 161	}
 162
 163	mComboTexGen = getChild<LLComboBox>("combobox texgen");
 164	if(mComboTexGen)
 165	{
 166		mComboTexGen->setCommitCallback(LLPanelFace::onCommitTexGen, this);
 167		mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);	
 168	}
 169
 170	mCtrlGlow = getChild<LLSpinCtrl>("glow");
 171	if(mCtrlGlow)
 172	{
 173		mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
 174	}
 175	
 176
 177	clearCtrls();
 178
 179	return TRUE;
 180}
 181
 182LLPanelFace::LLPanelFace()
 183:	LLPanel()
 184{
 185}
 186
 187
 188LLPanelFace::~LLPanelFace()
 189{
 190	// Children all cleaned up by default view destructor.
 191}
 192
 193
 194void LLPanelFace::sendTexture()
 195{
 196	LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("texture control");
 197	if(!mTextureCtrl) return;
 198	if( !mTextureCtrl->getTentative() )
 199	{
 200		// we grab the item id first, because we want to do a
 201		// permissions check in the selection manager. ARGH!
 202		LLUUID id = mTextureCtrl->getImageItemID();
 203		if(id.isNull())
 204		{
 205			id = mTextureCtrl->getImageAssetID();
 206		}
 207		LLSelectMgr::getInstance()->selectionSetImage(id);
 208	}
 209}
 210
 211void LLPanelFace::sendBump()
 212{	
 213	LLComboBox*	mComboBumpiness = getChild<LLComboBox>("combobox bumpiness");
 214	if(!mComboBumpiness)return;
 215	U8 bump = (U8) mComboBumpiness->getCurrentIndex() & TEM_BUMP_MASK;
 216	LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
 217}
 218
 219void LLPanelFace::sendTexGen()
 220{
 221	LLComboBox*	mComboTexGen = getChild<LLComboBox>("combobox texgen");
 222	if(!mComboTexGen)return;
 223	U8 tex_gen = (U8) mComboTexGen->getCurrentIndex() << TEM_TEX_GEN_SHIFT;
 224	LLSelectMgr::getInstance()->selectionSetTexGen( tex_gen );
 225}
 226
 227void LLPanelFace::sendShiny()
 228{
 229	LLComboBox*	mComboShininess = getChild<LLComboBox>("combobox shininess");
 230	if(!mComboShininess)return;
 231	U8 shiny = (U8) mComboShininess->getCurrentIndex() & TEM_SHINY_MASK;
 232	LLSelectMgr::getInstance()->selectionSetShiny( shiny );
 233}
 234
 235void LLPanelFace::sendFullbright()
 236{
 237	LLCheckBoxCtrl*	mCheckFullbright = getChild<LLCheckBoxCtrl>("checkbox fullbright");
 238	if(!mCheckFullbright)return;
 239	U8 fullbright = mCheckFullbright->get() ? TEM_FULLBRIGHT_MASK : 0;
 240	LLSelectMgr::getInstance()->selectionSetFullbright( fullbright );
 241}
 242
 243void LLPanelFace::sendColor()
 244{
 245	
 246	LLColorSwatchCtrl*	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
 247	if(!mColorSwatch)return;
 248	LLColor4 color = mColorSwatch->get();
 249
 250	LLSelectMgr::getInstance()->selectionSetColorOnly( color );
 251}
 252
 253void LLPanelFace::sendAlpha()
 254{	
 255	LLSpinCtrl*	mCtrlColorTransp = getChild<LLSpinCtrl>("ColorTrans");
 256	if(!mCtrlColorTransp)return;
 257	F32 alpha = (100.f - mCtrlColorTransp->get()) / 100.f;
 258
 259	LLSelectMgr::getInstance()->selectionSetAlphaOnly( alpha );
 260}
 261
 262
 263void LLPanelFace::sendGlow()
 264{
 265	LLSpinCtrl* mCtrlGlow = getChild<LLSpinCtrl>("glow");
 266	llassert(mCtrlGlow);
 267	if (mCtrlGlow)
 268	{
 269		F32 glow = mCtrlGlow->get();
 270		LLSelectMgr::getInstance()->selectionSetGlow( glow );
 271	}
 272}
 273
 274struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
 275{
 276	LLPanelFaceSetTEFunctor(LLPanelFace* panel) : mPanel(panel) {}
 277	virtual bool apply(LLViewerObject* object, S32 te)
 278	{
 279		BOOL valid;
 280		F32 value;
 281		LLSpinCtrl*	ctrlTexScaleS = mPanel->getChild<LLSpinCtrl>("TexScaleU");
 282		LLSpinCtrl*	ctrlTexScaleT = mPanel->getChild<LLSpinCtrl>("TexScaleV");
 283		LLSpinCtrl*	ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU");
 284		LLSpinCtrl*	ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV");
 285		LLSpinCtrl*	ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot");
 286		LLCheckBoxCtrl*	checkFlipScaleS = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip s");
 287		LLCheckBoxCtrl*	checkFlipScaleT = mPanel->getChild<LLCheckBoxCtrl>("checkbox flip t");
 288		LLComboBox*		comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen");
 289		llassert(comboTexGen);
 290		llassert(object);
 291
 292		if (ctrlTexScaleS)
 293		{
 294			valid = !ctrlTexScaleS->getTentative() || !checkFlipScaleS->getTentative();
 295			if (valid)
 296			{
 297				value = ctrlTexScaleS->get();
 298				if( checkFlipScaleS->get() )
 299				{
 300					value = -value;
 301				}
 302				if (comboTexGen &&
 303				    comboTexGen->getCurrentIndex() == 1)
 304				{
 305					value *= 0.5f;
 306				}
 307				object->setTEScaleS( te, value );
 308			}
 309		}
 310
 311		if (ctrlTexScaleT)
 312		{
 313			valid = !ctrlTexScaleT->getTentative() || !checkFlipScaleT->getTentative();
 314			if (valid)
 315			{
 316				value = ctrlTexScaleT->get();
 317				if( checkFlipScaleT->get() )
 318				{
 319					value = -value;
 320				}
 321				if (comboTexGen &&
 322				    comboTexGen->getCurrentIndex() == 1)
 323				{
 324					value *= 0.5f;
 325				}
 326				object->setTEScaleT( te, value );
 327			}
 328		}
 329
 330		if (ctrlTexOffsetS)
 331		{
 332			valid = !ctrlTexOffsetS->getTentative();
 333			if (valid)
 334			{
 335				value = ctrlTexOffsetS->get();
 336				object->setTEOffsetS( te, value );
 337			}
 338		}
 339
 340		if (ctrlTexOffsetT)
 341		{
 342			valid = !ctrlTexOffsetT->getTentative();
 343			if (valid)
 344			{
 345				value = ctrlTexOffsetT->get();
 346				object->setTEOffsetT( te, value );
 347			}
 348		}
 349
 350		if (ctrlTexRotation)
 351		{
 352			valid = !ctrlTexRotation->getTentative();
 353			if (valid)
 354			{
 355				value = ctrlTexRotation->get() * DEG_TO_RAD;
 356				object->setTERotation( te, value );
 357			}
 358		}
 359		return true;
 360	}
 361private:
 362	LLPanelFace* mPanel;
 363};
 364
 365// Functor that aligns a face to mCenterFace
 366struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor
 367{
 368	LLPanelFaceSetAlignedTEFunctor(LLPanelFace* panel, LLFace* center_face) :
 369		mPanel(panel),
 370		mCenterFace(center_face) {}
 371
 372	virtual bool apply(LLViewerObject* object, S32 te)
 373	{
 374		LLFace* facep = object->mDrawable->getFace(te);
 375		if (!facep)
 376		{
 377			return true;
 378		}
 379
 380		if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
 381		{
 382			return true;
 383		}
 384
 385		bool set_aligned = true;
 386		if (facep == mCenterFace)
 387		{
 388			set_aligned = false;
 389		}
 390		if (set_aligned)
 391		{
 392			LLVector2 uv_offset, uv_scale;
 393			F32 uv_rot;
 394			set_aligned = facep->calcAlignedPlanarTE(mCenterFace, &uv_offset, &uv_scale, &uv_rot);
 395			if (set_aligned)
 396			{
 397				object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]);
 398				object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]);
 399				object->setTERotation(te, uv_rot);
 400			}
 401		}
 402		if (!set_aligned)
 403		{
 404			LLPanelFaceSetTEFunctor setfunc(mPanel);
 405			setfunc.apply(object, te);
 406		}
 407		return true;
 408	}
 409private:
 410	LLPanelFace* mPanel;
 411	LLFace* mCenterFace;
 412};
 413
 414// Functor that tests if a face is aligned to mCenterFace
 415struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor
 416{
 417	LLPanelFaceGetIsAlignedTEFunctor(LLFace* center_face) :
 418		mCenterFace(center_face) {}
 419
 420	virtual bool apply(LLViewerObject* object, S32 te)
 421	{
 422		LLFace* facep = object->mDrawable->getFace(te);
 423		if (!facep)
 424		{
 425			return false;
 426		}
 427
 428		if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te)
 429		{ //volume face does not exist, can't be aligned
 430			return false;
 431		}
 432
 433		if (facep == mCenterFace)
 434		{
 435			return true;
 436		}
 437		
 438		LLVector2 aligned_st_offset, aligned_st_scale;
 439		F32 aligned_st_rot;
 440		if ( facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot) )
 441		{
 442			const LLTextureEntry* tep = facep->getTextureEntry();
 443			LLVector2 st_offset, st_scale;
 444			tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
 445			tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
 446			F32 st_rot = tep->getRotation();
 447			// needs a fuzzy comparison, because of fp errors
 448			if (is_approx_equal_fraction(st_offset.mV[VX], aligned_st_offset.mV[VX], 12) && 
 449				is_approx_equal_fraction(st_offset.mV[VY], aligned_st_offset.mV[VY], 12) && 
 450				is_approx_equal_fraction(st_scale.mV[VX], aligned_st_scale.mV[VX], 12) &&
 451				is_approx_equal_fraction(st_scale.mV[VY], aligned_st_scale.mV[VY], 12) &&
 452				is_approx_equal_fraction(st_rot, aligned_st_rot, 14))
 453			{
 454				return true;
 455			}
 456		}
 457		return false;
 458	}
 459private:
 460	LLFace* mCenterFace;
 461};
 462
 463struct LLPanelFaceSendFunctor : public LLSelectedObjectFunctor
 464{
 465	virtual bool apply(LLViewerObject* object)
 466	{
 467		object->sendTEUpdate();
 468		return true;
 469	}
 470};
 471
 472void LLPanelFace::sendTextureInfo()
 473{
 474	if ((bool)childGetValue("checkbox planar align").asBoolean())
 475	{
 476		struct f1 : public LLSelectedTEGetFunctor<LLFace *>
 477		{
 478			LLFace* get(LLViewerObject* object, S32 te)
 479			{
 480				return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
 481			}
 482		} get_last_face_func;
 483		LLFace* last_face;
 484		LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_last_face_func, last_face);
 485
 486		LLPanelFaceSetAlignedTEFunctor setfunc(this, last_face);
 487		LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
 488	}
 489	else
 490	{
 491		LLPanelFaceSetTEFunctor setfunc(this);
 492		LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
 493	}
 494
 495	LLPanelFaceSendFunctor sendfunc;
 496	LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
 497}
 498
 499void LLPanelFace::getState()
 500{
 501	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
 502
 503	if( objectp
 504		&& objectp->getPCode() == LL_PCODE_VOLUME
 505		&& objectp->permModify())
 506	{
 507		BOOL editable = objectp->permModify();
 508
 509		// only turn on auto-adjust button if there is a media renderer and the media is loaded
 510		getChildView("textbox autofix")->setEnabled(editable);
 511		getChildView("button align")->setEnabled(editable);
 512		
 513		//if ( LLMediaEngine::getInstance()->getMediaRenderer () )
 514		//	if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
 515		//	{	
 516		//		
 517		//		//mLabelTexAutoFix->setEnabled ( editable );
 518		//		
 519		//		//mBtnAutoFix->setEnabled ( editable );
 520		//	}
 521		getChildView("button apply")->setEnabled(editable);
 522
 523		bool identical;
 524		LLTextureCtrl*	texture_ctrl = getChild<LLTextureCtrl>("texture control");
 525		
 526		// Texture
 527		{
 528			LLUUID id;
 529			struct f1 : public LLSelectedTEGetFunctor<LLUUID>
 530			{
 531				LLUUID get(LLViewerObject* object, S32 te_index)
 532				{
 533					LLUUID id;
 534					
 535					LLViewerTexture* image = object->getTEImage(te_index);
 536					if (image) id = image->getID();
 537					
 538					if (!id.isNull() && LLViewerMedia::textureHasMedia(id))
 539					{
 540						LLTextureEntry *te = object->getTE(te_index);
 541						if (te)
 542						{
 543							LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID()) : NULL ;
 544							if(!tex)
 545							{
 546								tex = LLViewerFetchedTexture::sDefaultImagep;
 547							}
 548							if (tex)
 549							{
 550								id = tex->getID();
 551							}
 552						}
 553					}
 554					return id;
 555				}
 556			} func;
 557			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
 558
 559			if(LLViewerMedia::textureHasMedia(id))
 560			{
 561				getChildView("textbox autofix")->setEnabled(editable);
 562				getChildView("button align")->setEnabled(editable);
 563			}
 564			
 565			if (identical)
 566			{
 567				// All selected have the same texture
 568				if(texture_ctrl)
 569				{
 570					texture_ctrl->setTentative( FALSE );
 571					texture_ctrl->setEnabled( editable );
 572					texture_ctrl->setImageAssetID( id );
 573				}
 574			}
 575			else
 576			{
 577				if(texture_ctrl)
 578				{
 579					if( id.isNull() )
 580					{
 581						// None selected
 582						texture_ctrl->setTentative( FALSE );
 583						texture_ctrl->setEnabled( FALSE );
 584						texture_ctrl->setImageAssetID( LLUUID::null );
 585					}
 586					else
 587					{
 588						// Tentative: multiple selected with different textures
 589						texture_ctrl->setTentative( TRUE );
 590						texture_ctrl->setEnabled( editable );
 591						texture_ctrl->setImageAssetID( id );
 592					}
 593				}
 594			}
 595		}
 596
 597		
 598		LLAggregatePermissions texture_perms;
 599		if(texture_ctrl)
 600		{
 601// 			texture_ctrl->setValid( editable );
 602		
 603			if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
 604			{
 605				BOOL can_copy = 
 606					texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || 
 607					texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
 608				BOOL can_transfer = 
 609					texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || 
 610					texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
 611				texture_ctrl->setCanApplyImmediately(can_copy && can_transfer);
 612			}
 613			else
 614			{
 615				texture_ctrl->setCanApplyImmediately(FALSE);
 616			}
 617		}
 618
 619
 620		// planar align
 621		bool align_planar = false;
 622		bool identical_planar_aligned = false;
 623		bool is_planar = false;
 624		{
 625			LLCheckBoxCtrl*	cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
 626			align_planar = (cb_planar_align && cb_planar_align->get());
 627			struct f1 : public LLSelectedTEGetFunctor<bool>
 628			{
 629				bool get(LLViewerObject* object, S32 face)
 630				{
 631					return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR);
 632				}
 633			} func;
 634
 635			bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar );
 636			bool enabled = (editable && texgens_identical && is_planar);
 637			childSetValue("checkbox planar align", align_planar && enabled);
 638			childSetEnabled("checkbox planar align", enabled);
 639
 640			if (align_planar && enabled)
 641			{
 642				struct f2 : public LLSelectedTEGetFunctor<LLFace *>
 643				{
 644					LLFace* get(LLViewerObject* object, S32 te)
 645					{
 646						return (object->mDrawable) ? object->mDrawable->getFace(te): NULL;
 647					}
 648				} get_te_face_func;
 649				LLFace* last_face;
 650				LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&get_te_face_func, last_face);
 651				LLPanelFaceGetIsAlignedTEFunctor get_is_aligend_func(last_face);
 652				// this will determine if the texture param controls are tentative:
 653				identical_planar_aligned = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&get_is_aligend_func);
 654			}
 655		}
 656		
 657		// Texture scale
 658		{
 659			F32 scale_s = 1.f;
 660			struct f2 : public LLSelectedTEGetFunctor<F32>
 661			{
 662				F32 get(LLViewerObject* object, S32 face)
 663				{
 664					return object->getTE(face)->mScaleS;
 665				}
 666			} func;
 667			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_s );
 668			identical = align_planar ? identical_planar_aligned : identical;
 669			getChild<LLUICtrl>("TexScaleU")->setValue(editable ? llabs(scale_s) : 0);
 670			getChild<LLUICtrl>("TexScaleU")->setTentative(LLSD((BOOL)(!identical)));
 671			getChildView("TexScaleU")->setEnabled(editable);
 672			getChild<LLUICtrl>("checkbox flip s")->setValue(LLSD((BOOL)(scale_s < 0 ? TRUE : FALSE )));
 673			getChild<LLUICtrl>("checkbox flip s")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
 674			getChildView("checkbox flip s")->setEnabled(editable);
 675		}
 676
 677		{
 678			F32 scale_t = 1.f;
 679			struct f3 : public LLSelectedTEGetFunctor<F32>
 680			{
 681				F32 get(LLViewerObject* object, S32 face)
 682				{
 683					return object->getTE(face)->mScaleT;
 684				}
 685			} func;
 686			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, scale_t );
 687			identical = align_planar ? identical_planar_aligned : identical;
 688
 689			getChild<LLUICtrl>("TexScaleV")->setValue(llabs(editable ? llabs(scale_t) : 0));
 690			getChild<LLUICtrl>("TexScaleV")->setTentative(LLSD((BOOL)(!identical)));
 691			getChildView("TexScaleV")->setEnabled(editable);
 692			getChild<LLUICtrl>("checkbox flip t")->setValue(LLSD((BOOL)(scale_t< 0 ? TRUE : FALSE )));
 693			getChild<LLUICtrl>("checkbox flip t")->setTentative(LLSD((BOOL)((!identical) ? TRUE : FALSE )));
 694			getChildView("checkbox flip t")->setEnabled(editable);
 695		}
 696
 697		// Texture offset
 698		{
 699			getChildView("tex offset")->setEnabled(editable);
 700			F32 offset_s = 0.f;
 701			struct f4 : public LLSelectedTEGetFunctor<F32>
 702			{
 703				F32 get(LLViewerObject* object, S32 face)
 704				{
 705					return object->getTE(face)->mOffsetS;
 706				}
 707			} func;
 708			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_s );
 709			identical = align_planar ? identical_planar_aligned : identical;
 710			getChild<LLUICtrl>("TexOffsetU")->setValue(editable ? offset_s : 0);
 711			getChild<LLUICtrl>("TexOffsetU")->setTentative(!identical);
 712			getChildView("TexOffsetU")->setEnabled(editable);
 713		}
 714
 715		{
 716			F32 offset_t = 0.f;
 717			struct f5 : public LLSelectedTEGetFunctor<F32>
 718			{
 719				F32 get(LLViewerObject* object, S32 face)
 720				{
 721					return object->getTE(face)->mOffsetT;
 722				}
 723			} func;
 724			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, offset_t );
 725			identical = align_planar ? identical_planar_aligned : identical;
 726			getChild<LLUICtrl>("TexOffsetV")->setValue(editable ? offset_t : 0);
 727			getChild<LLUICtrl>("TexOffsetV")->setTentative(!identical);
 728			getChildView("TexOffsetV")->setEnabled(editable);
 729		}
 730
 731		// Texture rotation
 732		{
 733			F32 rotation = 0.f;
 734			struct f6 : public LLSelectedTEGetFunctor<F32>
 735			{
 736				F32 get(LLViewerObject* object, S32 face)
 737				{
 738					return object->getTE(face)->mRotation;
 739				}
 740			} func;
 741			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, rotation );
 742			identical = align_planar ? identical_planar_aligned : identical;
 743			getChild<LLUICtrl>("TexRot")->setValue(editable ? rotation * RAD_TO_DEG : 0);
 744			getChild<LLUICtrl>("TexRot")->setTentative(!identical);
 745			getChildView("TexRot")->setEnabled(editable);
 746		}
 747
 748		// Color swatch
 749		LLColorSwatchCtrl*	mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
 750		LLColor4 color = LLColor4::white;
 751		if(mColorSwatch)
 752		{
 753			struct f7 : public LLSelectedTEGetFunctor<LLColor4>
 754			{
 755				LLColor4 get(LLViewerObject* object, S32 face)
 756				{
 757					return object->getTE(face)->getColor();
 758				}
 759			} func;
 760			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, color );
 761			
 762			mColorSwatch->setOriginal(color);
 763			mColorSwatch->set(color, TRUE);
 764
 765			mColorSwatch->setValid(editable);
 766			mColorSwatch->setEnabled( editable );
 767			mColorSwatch->setCanApplyImmediately( editable );
 768		}
 769		// Color transparency
 770		{
 771			getChildView("color trans")->setEnabled(editable);
 772		}
 773
 774		F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
 775		{
 776			getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
 777			getChildView("ColorTrans")->setEnabled(editable);
 778		}
 779
 780		{
 781			F32 glow = 0.f;
 782			struct f8 : public LLSelectedTEGetFunctor<F32>
 783			{
 784				F32 get(LLViewerObject* object, S32 face)
 785				{
 786					return object->getTE(face)->getGlow();
 787				}
 788			} func;
 789			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, glow );
 790
 791			getChild<LLUICtrl>("glow")->setValue(glow);
 792			getChildView("glow")->setEnabled(editable);
 793			getChild<LLUICtrl>("glow")->setTentative(!identical);
 794			getChildView("glow label")->setEnabled(editable);
 795
 796		}
 797
 798		// Bump
 799		{
 800			F32 shinyf = 0.f;
 801			struct f9 : public LLSelectedTEGetFunctor<F32>
 802			{
 803				F32 get(LLViewerObject* object, S32 face)
 804				{
 805					return (F32)(object->getTE(face)->getShiny());
 806				}
 807			} func;
 808			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, shinyf );
 809			LLCtrlSelectionInterface* combobox_shininess =
 810			      childGetSelectionInterface("combobox shininess");
 811			if (combobox_shininess)
 812			{
 813				combobox_shininess->selectNthItem((S32)shinyf);
 814			}
 815			else
 816			{
 817				llwarns << "failed childGetSelectionInterface for 'combobox shininess'" << llendl;
 818			}
 819			getChildView("combobox shininess")->setEnabled(editable);
 820			getChild<LLUICtrl>("combobox shininess")->setTentative(!identical);
 821			getChildView("label shininess")->setEnabled(editable);
 822		}
 823
 824		{
 825			F32 bumpf = 0.f;
 826			struct f10 : public LLSelectedTEGetFunctor<F32>
 827			{
 828				F32 get(LLViewerObject* object, S32 face)
 829				{
 830					return (F32)(object->getTE(face)->getBumpmap());
 831				}
 832			} func;
 833			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, bumpf );
 834			LLCtrlSelectionInterface* combobox_bumpiness =
 835			      childGetSelectionInterface("combobox bumpiness");
 836			if (combobox_bumpiness)
 837			{
 838				combobox_bumpiness->selectNthItem((S32)bumpf);
 839			}
 840			else
 841			{
 842				llwarns << "failed childGetSelectionInterface for 'combobox bumpiness'" << llendl;
 843			}
 844			getChildView("combobox bumpiness")->setEnabled(editable);
 845			getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical);
 846			getChildView("label bumpiness")->setEnabled(editable);
 847		}
 848
 849		{
 850			F32 genf = 0.f;
 851			struct f11 : public LLSelectedTEGetFunctor<F32>
 852			{
 853				F32 get(LLViewerObject* object, S32 face)
 854				{
 855					return (F32)(object->getTE(face)->getTexGen());
 856				}
 857			} func;
 858			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, genf );
 859			S32 selected_texgen = ((S32) genf) >> TEM_TEX_GEN_SHIFT;
 860			LLCtrlSelectionInterface* combobox_texgen =
 861			      childGetSelectionInterface("combobox texgen");
 862			if (combobox_texgen)
 863			{
 864				combobox_texgen->selectNthItem(selected_texgen);
 865			}
 866			else
 867			{
 868				llwarns << "failed childGetSelectionInterface for 'combobox texgen'" << llendl;
 869			}
 870			getChildView("combobox texgen")->setEnabled(editable);
 871			getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
 872			getChildView("tex gen")->setEnabled(editable);
 873
 874			if (selected_texgen == 1)
 875			{
 876				getChild<LLUICtrl>("TexScaleU")->setValue(2.0f * getChild<LLUICtrl>("TexScaleU")->getValue().asReal() );
 877				getChild<LLUICtrl>("TexScaleV")->setValue(2.0f * getChild<LLUICtrl>("TexScaleV")->getValue().asReal() );
 878			}
 879
 880		}
 881
 882		{
 883			F32 fullbrightf = 0.f;
 884			struct f12 : public LLSelectedTEGetFunctor<F32>
 885			{
 886				F32 get(LLViewerObject* object, S32 face)
 887				{
 888					return (F32)(object->getTE(face)->getFullbright());
 889				}
 890			} func;
 891			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, fullbrightf );
 892
 893			getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)fullbrightf);
 894			getChildView("checkbox fullbright")->setEnabled(editable);
 895			getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical);
 896		}
 897		
 898		// Repeats per meter label
 899		{
 900			getChildView("rpt")->setEnabled(editable);
 901		}
 902
 903		// Repeats per meter
 904		{
 905			F32 repeats = 1.f;
 906			struct f13 : public LLSelectedTEGetFunctor<F32>
 907			{
 908				F32 get(LLViewerObject* object, S32 face)
 909				{
 910					U32 s_axis = VX;
 911					U32 t_axis = VY;
 912					// BUG: Only repeats along S axis
 913					// BUG: Only works for boxes.
 914					LLPrimitive::getTESTAxes(face, &s_axis, &t_axis);
 915					return object->getTE(face)->mScaleS / object->getScale().mV[s_axis];
 916				}
 917			} func;			
 918			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, repeats );
 919			
 920			getChild<LLUICtrl>("rptctrl")->setValue(editable ? repeats : 0);
 921			getChild<LLUICtrl>("rptctrl")->setTentative(!identical);
 922			LLComboBox*	mComboTexGen = getChild<LLComboBox>("combobox texgen");
 923			if (mComboTexGen)
 924			{
 925				BOOL enabled = editable && (!mComboTexGen || mComboTexGen->getCurrentIndex() != 1);
 926				getChildView("rptctrl")->setEnabled(enabled);
 927				getChildView("button apply")->setEnabled(enabled);
 928			}
 929		}
 930
 931		// Set variable values for numeric expressions
 932		LLCalc* calcp = LLCalc::getInstance();
 933		calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal());
 934		calcp->setVar(LLCalc::TEX_V_SCALE, childGetValue("TexScaleV").asReal());
 935		calcp->setVar(LLCalc::TEX_U_OFFSET, childGetValue("TexOffsetU").asReal());
 936		calcp->setVar(LLCalc::TEX_V_OFFSET, childGetValue("TexOffsetV").asReal());
 937		calcp->setVar(LLCalc::TEX_ROTATION, childGetValue("TexRot").asReal());
 938		calcp->setVar(LLCalc::TEX_TRANSPARENCY, childGetValue("ColorTrans").asReal());
 939		calcp->setVar(LLCalc::TEX_GLOW, childGetValue("glow").asReal());
 940	}
 941	else
 942	{
 943		// Disable all UICtrls
 944		clearCtrls();
 945
 946		// Disable non-UICtrls
 947		LLTextureCtrl*	texture_ctrl = getChild<LLTextureCtrl>("texture control"); 
 948		if(texture_ctrl)
 949		{
 950			texture_ctrl->setImageAssetID( LLUUID::null );
 951			texture_ctrl->setEnabled( FALSE );  // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl.
 952// 			texture_ctrl->setValid(FALSE);
 953		}
 954		LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
 955		if(mColorSwatch)
 956		{
 957			mColorSwatch->setEnabled( FALSE );			
 958			mColorSwatch->setFallbackImageName("locked_image.j2c" );
 959			mColorSwatch->setValid(FALSE);
 960		}
 961		getChildView("color trans")->setEnabled(FALSE);
 962		getChildView("rpt")->setEnabled(FALSE);
 963		getChildView("tex offset")->setEnabled(FALSE);
 964		getChildView("tex gen")->setEnabled(FALSE);
 965		getChildView("label shininess")->setEnabled(FALSE);
 966		getChildView("label bumpiness")->setEnabled(FALSE);
 967
 968		getChildView("textbox autofix")->setEnabled(FALSE);
 969
 970		getChildView("button align")->setEnabled(FALSE);
 971		getChildView("button apply")->setEnabled(FALSE);
 972		//getChildView("has media")->setEnabled(FALSE);
 973		//getChildView("media info set")->setEnabled(FALSE);
 974		
 975
 976		// Set variable values for numeric expressions
 977		LLCalc* calcp = LLCalc::getInstance();
 978		calcp->clearVar(LLCalc::TEX_U_SCALE);
 979		calcp->clearVar(LLCalc::TEX_V_SCALE);
 980		calcp->clearVar(LLCalc::TEX_U_OFFSET);
 981		calcp->clearVar(LLCalc::TEX_V_OFFSET);
 982		calcp->clearVar(LLCalc::TEX_ROTATION);
 983		calcp->clearVar(LLCalc::TEX_TRANSPARENCY);
 984		calcp->clearVar(LLCalc::TEX_GLOW);		
 985	}
 986}
 987
 988
 989void LLPanelFace::refresh()
 990{
 991	getState();
 992}
 993
 994//
 995// Static functions
 996//
 997
 998// static
 999F32 LLPanelFace::valueGlow(LLViewerObject* object, S32 face)
1000{
1001	return (F32)(object->getTE(face)->getGlow());
1002}
1003
1004
1005void LLPanelFace::onCommitColor(const LLSD& data)
1006{
1007	sendColor();
1008}
1009
1010void LLPanelFace::onCommitAlpha(const LLSD& data)
1011{
1012	sendAlpha();
1013}
1014
1015void LLPanelFace::onCancelColor(const LLSD& data)
1016{
1017	LLSelectMgr::getInstance()->selectionRevertColors();
1018}
1019
1020void LLPanelFace::onSelectColor(const LLSD& data)
1021{
1022	LLSelectMgr::getInstance()->saveSelectedObjectColors();
1023	sendColor();
1024}
1025
1026// static
1027void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
1028{
1029	LLPanelFace* self = (LLPanelFace*) userdata;
1030	self->sendBump();
1031}
1032
1033// static
1034void LLPanelFace::onCommitTexGen(LLUICtrl* ctrl, void* userdata)
1035{
1036	LLPanelFace* self = (LLPanelFace*) userdata;
1037	self->sendTexGen();
1038}
1039
1040// static
1041void LLPanelFace::onCommitShiny(LLUICtrl* ctrl, void* userdata)
1042{
1043	LLPanelFace* self = (LLPanelFace*) userdata;
1044	self->sendShiny();
1045}
1046
1047// static
1048void LLPanelFace::onCommitFullbright(LLUICtrl* ctrl, void* userdata)
1049{
1050	LLPanelFace* self = (LLPanelFace*) userdata;
1051	self->sendFullbright();
1052}
1053
1054// static
1055void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
1056{
1057	LLPanelFace* self = (LLPanelFace*) userdata;
1058	self->sendGlow();
1059}
1060
1061// static
1062BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
1063{
1064	BOOL accept = TRUE;
1065	for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
1066		 iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
1067	{
1068		LLSelectNode* node = *iter;
1069		LLViewerObject* obj = node->getObject();
1070		if(!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
1071		{
1072			accept = FALSE;
1073			break;
1074		}
1075	}
1076	return accept;
1077}
1078
1079void LLPanelFace::onCommitTexture( const LLSD& data )
1080{
1081	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
1082	sendTexture();
1083}
1084
1085void LLPanelFace::onCancelTexture(const LLSD& data)
1086{
1087	LLSelectMgr::getInstance()->selectionRevertTextures();
1088}
1089
1090void LLPanelFace::onSelectTexture(const LLSD& data)
1091{
1092	LLSelectMgr::getInstance()->saveSelectedObjectTextures();
1093	sendTexture();
1094}
1095
1096
1097// static
1098void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata )
1099{
1100	LLPanelFace* self = (LLPanelFace*) userdata;
1101	self->sendTextureInfo();
1102}
1103
1104// Commit the number of repeats per meter
1105// static
1106void LLPanelFace::onClickApply(void* userdata)
1107{
1108	LLPanelFace* self = (LLPanelFace*) userdata;
1109	
1110	gFocusMgr.setKeyboardFocus( NULL );
1111
1112	//F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get();
1113	F32 repeats_per_meter = (F32)self->getChild<LLUICtrl>("rptctrl")->getValue().asReal();//self->mCtrlRepeatsPerMeter->get();
1114	LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
1115}
1116
1117struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
1118{
1119	virtual bool apply(LLViewerObject* object, S32 te)
1120	{
1121		viewer_media_t pMediaImpl;
1122				
1123		const LLTextureEntry* tep = object->getTE(te);
1124		const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
1125		if ( mep )
1126		{
1127			pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
1128		}
1129		
1130		if ( pMediaImpl.isNull())
1131		{
1132			// If we didn't find face media for this face, check whether this face is showing parcel media.
1133			pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
1134		}
1135		
1136		if ( pMediaImpl.notNull())
1137		{
1138			LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
1139			if(media)
1140			{
1141				S32 media_width = media->getWidth();
1142				S32 media_height = media->getHeight();
1143				S32 texture_width = media->getTextureWidth();
1144				S32 texture_height = media->getTextureHeight();
1145				F32 scale_s = (F32)media_width / (F32)texture_width;
1146				F32 scale_t = (F32)media_height / (F32)texture_height;
1147
1148				// set scale and adjust offset
1149				object->setTEScaleS( te, scale_s );
1150				object->setTEScaleT( te, scale_t );	// don't need to flip Y anymore since QT does this for us now.
1151				object->setTEOffsetS( te, -( 1.0f - scale_s ) / 2.0f );
1152				object->setTEOffsetT( te, -( 1.0f - scale_t ) / 2.0f );
1153			}
1154		}
1155		return true;
1156	};
1157};
1158
1159void LLPanelFace::onClickAutoFix(void* userdata)
1160{
1161	LLPanelFaceSetMediaFunctor setfunc;
1162	LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc);
1163
1164	LLPanelFaceSendFunctor sendfunc;
1165	LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
1166}
1167
1168
1169
1170// TODO: I don't know who put these in or what these are for???
1171void LLPanelFace::setMediaURL(const std::string& url)
1172{
1173}
1174void LLPanelFace::setMediaType(const std::string& mime_type)
1175{
1176}
1177
1178// static
1179void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
1180{
1181	LLPanelFace* self = (LLPanelFace*) userdata;
1182	self->getState();
1183	self->sendTextureInfo();
1184}
1185