PageRenderTime 43ms CodeModel.GetById 7ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llscrollingpanelparam.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 358 lines | 253 code | 54 blank | 51 comment | 29 complexity | 5f54da49d7ae913844837fa3d48f94c6 MD5 | raw file
  1/** 
  2 * @file llscrollingpanelparam.cpp
  3 * @brief UI panel for a list of visual param panels
  4 *
  5 * $LicenseInfo:firstyear=2009&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#include "llscrollingpanelparam.h"
 30#include "llviewerjointmesh.h"
 31#include "llviewervisualparam.h"
 32#include "llwearable.h"
 33#include "llviewervisualparam.h"
 34#include "lltoolmorph.h"
 35#include "lltrans.h"
 36#include "llbutton.h"
 37#include "llsliderctrl.h"
 38#include "llagent.h"
 39#include "llviewborder.h"
 40#include "llvoavatarself.h"
 41
 42// Constants for LLPanelVisualParam
 43const F32 LLScrollingPanelParam::PARAM_STEP_TIME_THRESHOLD = 0.25f;
 44
 45const S32 LLScrollingPanelParam::PARAM_HINT_WIDTH = 128;
 46const S32 LLScrollingPanelParam::PARAM_HINT_HEIGHT = 128;
 47
 48// LLScrollingPanelParam
 49//static
 50S32 LLScrollingPanelParam::sUpdateDelayFrames = 0;
 51
 52LLScrollingPanelParam::LLScrollingPanelParam( const LLPanel::Params& panel_params,
 53					      LLViewerJointMesh* mesh, LLViewerVisualParam* param, BOOL allow_modify, LLWearable* wearable, LLJoint* jointp, BOOL use_hints )
 54    : LLScrollingPanelParamBase( panel_params, mesh, param, allow_modify, wearable, jointp, use_hints)
 55{
 56	// *HACK To avoid hard coding texture position, lets use border's position for texture. 
 57	LLViewBorder* left_border = getChild<LLViewBorder>("left_border");
 58
 59	static LLUICachedControl<S32> slider_ctrl_height ("UISliderctrlHeight", 0);
 60	S32 pos_x = left_border->getRect().mLeft + left_border->getBorderWidth();
 61	S32 pos_y = left_border->getRect().mBottom + left_border->getBorderWidth();
 62	F32 min_weight = param->getMinWeight();
 63	F32 max_weight = param->getMaxWeight();
 64
 65	mHintMin = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), wearable,  min_weight, jointp);
 66	pos_x = getChild<LLViewBorder>("right_border")->getRect().mLeft + left_border->getBorderWidth();
 67	mHintMax = new LLVisualParamHint( pos_x, pos_y, PARAM_HINT_WIDTH, PARAM_HINT_HEIGHT, mesh, (LLViewerVisualParam*) wearable->getVisualParam(param->getID()), wearable, max_weight, jointp );
 68	
 69	mHintMin->setAllowsUpdates( FALSE );
 70	mHintMax->setAllowsUpdates( FALSE );
 71
 72	std::string min_name = LLTrans::getString(param->getMinDisplayName());
 73	std::string max_name = LLTrans::getString(param->getMaxDisplayName());
 74	getChild<LLUICtrl>("min param text")->setValue(min_name);
 75	getChild<LLUICtrl>("max param text")->setValue(max_name);
 76
 77	LLButton* less = getChild<LLButton>("less");
 78	if (less)
 79	{
 80		less->setMouseDownCallback( LLScrollingPanelParam::onHintMinMouseDown, this );
 81		less->setMouseUpCallback( LLScrollingPanelParam::onHintMinMouseUp, this );
 82		less->setHeldDownCallback( LLScrollingPanelParam::onHintMinHeldDown, this );
 83		less->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD );
 84	}
 85
 86	LLButton* more = getChild<LLButton>("more");
 87	if (more)
 88	{
 89		more->setMouseDownCallback( LLScrollingPanelParam::onHintMaxMouseDown, this );
 90		more->setMouseUpCallback( LLScrollingPanelParam::onHintMaxMouseUp, this );
 91		more->setHeldDownCallback( LLScrollingPanelParam::onHintMaxHeldDown, this );
 92		more->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD );
 93	}
 94
 95	setVisible(FALSE);
 96	setBorderVisible( FALSE );
 97}
 98
 99LLScrollingPanelParam::~LLScrollingPanelParam()
100{
101}
102void LLScrollingPanelParam::updatePanel(BOOL allow_modify)
103{
104	if (!mWearable)
105	{
106		// not editing a wearable just now, no update necessary
107		return;
108	}
109	LLScrollingPanelParamBase::updatePanel(allow_modify);
110
111	mHintMin->requestUpdate( sUpdateDelayFrames++ );
112	mHintMax->requestUpdate( sUpdateDelayFrames++ );
113	getChildView("less")->setEnabled(mAllowModify);
114	getChildView("more")->setEnabled(mAllowModify);
115}
116
117void LLScrollingPanelParam::setVisible( BOOL visible )
118{
119	if( getVisible() != visible )
120	{
121		LLPanel::setVisible( visible );
122		if (mHintMin)
123			mHintMin->setAllowsUpdates( visible );
124		if (mHintMax)
125			mHintMax->setAllowsUpdates( visible );
126
127		if( visible )
128		{
129			if (mHintMin)
130				mHintMin->setUpdateDelayFrames( sUpdateDelayFrames++ );
131			if (mHintMax)
132				mHintMax->setUpdateDelayFrames( sUpdateDelayFrames++ );
133		}
134	}
135}
136
137void LLScrollingPanelParam::draw()
138{
139	if( !mWearable )
140	{
141		return;
142	}
143	
144	getChildView("less")->setVisible( mHintMin->getVisible());
145	getChildView("more")->setVisible( mHintMax->getVisible());
146
147	// hide borders if texture has been loaded
148	getChildView("left_border")->setVisible( !mHintMin->getVisible());
149	getChildView("right_border")->setVisible( !mHintMax->getVisible());
150
151	// Draw all the children except for the labels
152	getChildView("min param text")->setVisible( FALSE );
153	getChildView("max param text")->setVisible( FALSE );
154	LLPanel::draw();
155	
156	// If we're in a focused floater, don't apply the floater's alpha to visual param hint,
157	// making its behavior similar to texture controls'.
158	F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
159
160	// Draw the hints over the "less" and "more" buttons.
161	gGL.pushUIMatrix();
162	{
163		const LLRect& r = mHintMin->getRect();
164		gGL.translateUI((F32)r.mLeft, (F32)r.mBottom, 0.f);
165		mHintMin->draw(alpha);
166	}
167	gGL.popUIMatrix();
168
169	gGL.pushUIMatrix();
170	{
171		const LLRect& r = mHintMax->getRect();
172		gGL.translateUI((F32)r.mLeft, (F32)r.mBottom, 0.f);
173		mHintMax->draw(alpha);
174	}
175	gGL.popUIMatrix();
176
177
178	// Draw labels on top of the buttons
179	getChildView("min param text")->setVisible( TRUE );
180	drawChild(getChild<LLView>("min param text"));
181
182	getChildView("max param text")->setVisible( TRUE );
183	drawChild(getChild<LLView>("max param text"));
184}
185
186// static
187void LLScrollingPanelParam::onSliderMouseDown(LLUICtrl* ctrl, void* userdata)
188{
189}
190
191// static
192void LLScrollingPanelParam::onSliderMouseUp(LLUICtrl* ctrl, void* userdata)
193{
194	LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata;
195	LLVisualParamHint::requestHintUpdates( self->mHintMin, self->mHintMax );
196}
197
198// static
199void LLScrollingPanelParam::onHintMinMouseDown( void* userdata )
200{
201	LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata;
202	self->onHintMouseDown( self->mHintMin );
203}
204
205// static
206void LLScrollingPanelParam::onHintMaxMouseDown( void* userdata )
207{
208	LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata;
209	self->onHintMouseDown( self->mHintMax );
210}
211
212
213void LLScrollingPanelParam::onHintMouseDown( LLVisualParamHint* hint )
214{
215	// morph towards this result
216	F32 current_weight = mWearable->getVisualParamWeight( hint->getVisualParam()->getID() );
217
218	// if we have maxed out on this morph, we shouldn't be able to click it
219	if( hint->getVisualParamWeight() != current_weight )
220	{
221		mMouseDownTimer.reset();
222		mLastHeldTime = 0.f;
223	}
224}
225
226// static
227void LLScrollingPanelParam::onHintMinHeldDown( void* userdata )
228{
229	LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata;
230	self->onHintHeldDown( self->mHintMin );
231}
232
233// static
234void LLScrollingPanelParam::onHintMaxHeldDown( void* userdata )
235{
236	LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata;
237	self->onHintHeldDown( self->mHintMax );
238}
239	
240void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint )
241{
242	F32 current_weight = mWearable->getVisualParamWeight( hint->getVisualParam()->getID() );
243
244	if (current_weight != hint->getVisualParamWeight() )
245	{
246		const F32 FULL_BLEND_TIME = 2.f;
247		F32 elapsed_time = mMouseDownTimer.getElapsedTimeF32() - mLastHeldTime;
248		mLastHeldTime += elapsed_time;
249
250		F32 new_weight;
251		if (current_weight > hint->getVisualParamWeight() )
252		{
253			new_weight = current_weight - (elapsed_time / FULL_BLEND_TIME);
254		}
255		else
256		{
257			new_weight = current_weight + (elapsed_time / FULL_BLEND_TIME);
258		}
259
260		// Make sure we're not taking the slider out of bounds
261		// (this is where some simple UI limits are stored)
262		F32 new_percent = weightToPercent(new_weight);
263		LLSliderCtrl* slider = getChild<LLSliderCtrl>("param slider");
264		if (slider)
265		{
266			if (slider->getMinValue() < new_percent
267				&& new_percent < slider->getMaxValue())
268			{
269				mWearable->setVisualParamWeight( hint->getVisualParam()->getID(), new_weight, FALSE);
270				mWearable->writeToAvatar();
271				gAgentAvatarp->updateVisualParams();
272
273				slider->setValue( weightToPercent( new_weight ) );
274			}
275		}
276	}
277}
278
279// static
280void LLScrollingPanelParam::onHintMinMouseUp( void* userdata )
281{
282	LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata;
283
284	F32 elapsed_time = self->mMouseDownTimer.getElapsedTimeF32();
285
286	LLVisualParamHint* hint = self->mHintMin;
287
288	if (elapsed_time < PARAM_STEP_TIME_THRESHOLD)
289	{
290		// step in direction
291		F32 current_weight = self->mWearable->getVisualParamWeight( hint->getVisualParam()->getID() );
292		F32 range = self->mHintMax->getVisualParamWeight() - self->mHintMin->getVisualParamWeight();
293		// step a fraction in the negative directiona
294		F32 new_weight = current_weight - (range / 10.f);
295		F32 new_percent = self->weightToPercent(new_weight);
296		LLSliderCtrl* slider = self->getChild<LLSliderCtrl>("param slider");
297		if (slider)
298		{
299			if (slider->getMinValue() < new_percent
300				&& new_percent < slider->getMaxValue())
301			{
302				self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE);
303				self->mWearable->writeToAvatar();
304				slider->setValue( self->weightToPercent( new_weight ) );
305			}
306		}
307	}
308
309	LLVisualParamHint::requestHintUpdates( self->mHintMin, self->mHintMax );
310}
311
312void LLScrollingPanelParam::onHintMaxMouseUp( void* userdata )
313{
314	LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata;
315
316	F32 elapsed_time = self->mMouseDownTimer.getElapsedTimeF32();
317
318	if (isAgentAvatarValid())
319	{
320		LLVisualParamHint* hint = self->mHintMax;
321
322		if (elapsed_time < PARAM_STEP_TIME_THRESHOLD)
323		{
324			// step in direction
325			F32 current_weight = self->mWearable->getVisualParamWeight( hint->getVisualParam()->getID() );
326			F32 range = self->mHintMax->getVisualParamWeight() - self->mHintMin->getVisualParamWeight();
327			// step a fraction in the negative direction
328			F32 new_weight = current_weight + (range / 10.f);
329			F32 new_percent = self->weightToPercent(new_weight);
330			LLSliderCtrl* slider = self->getChild<LLSliderCtrl>("param slider");
331			if (slider)
332			{
333				if (slider->getMinValue() < new_percent
334					&& new_percent < slider->getMaxValue())
335				{
336					self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE);
337					self->mWearable->writeToAvatar();
338					slider->setValue( self->weightToPercent( new_weight ) );
339				}
340			}
341		}
342	}
343
344	LLVisualParamHint::requestHintUpdates( self->mHintMin, self->mHintMax );
345}
346
347
348F32 LLScrollingPanelParam::weightToPercent( F32 weight )
349{
350	LLViewerVisualParam* param = mParam;
351	return (weight - param->getMinWeight()) /  (param->getMaxWeight() - param->getMinWeight()) * 100.f;
352}
353
354F32 LLScrollingPanelParam::percentToWeight( F32 percent )
355{
356	LLViewerVisualParam* param = mParam;
357	return percent / 100.f * (param->getMaxWeight() - param->getMinWeight()) + param->getMinWeight();
358}