PageRenderTime 105ms CodeModel.GetById 46ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llcolorswatch.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 373 lines | 269 code | 48 blank | 56 comment | 35 complexity | 4a21a84c3d3378a4be42ca2c8293559a MD5 | raw file
Possible License(s): LGPL-2.1
  1/** 
  2 * @file llcolorswatch.cpp
  3 * @brief LLColorSwatch class implementation
  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 "llcolorswatch.h"
 31
 32// Linden library includes
 33#include "v4color.h"
 34#include "llwindow.h"	// setCursor()
 35
 36// Project includes
 37#include "llui.h"
 38#include "llrender.h"
 39#include "lluiconstants.h"
 40#include "llviewercontrol.h"
 41#include "llbutton.h"
 42#include "lltextbox.h"
 43#include "llfloatercolorpicker.h"
 44#include "llviewborder.h"
 45#include "llviewertexturelist.h"
 46#include "llfocusmgr.h"
 47
 48static LLDefaultChildRegistry::Register<LLColorSwatchCtrl> r("color_swatch");
 49
 50LLColorSwatchCtrl::Params::Params()
 51:	color("color", LLColor4::white),
 52	can_apply_immediately("can_apply_immediately", false),
 53	alpha_background_image("alpha_background_image"),
 54	border_color("border_color"),
 55    label_width("label_width", -1),
 56	label_height("label_height", -1),
 57	caption_text("caption_text"),
 58	border("border")
 59{
 60}
 61
 62LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p)
 63:	LLUICtrl(p),
 64	mValid( TRUE ),
 65	mColor(p.color()),
 66	mCanApplyImmediately(p.can_apply_immediately),
 67	mAlphaGradientImage(p.alpha_background_image),
 68	mOnCancelCallback(p.cancel_callback()),
 69	mOnSelectCallback(p.select_callback()),
 70	mBorderColor(p.border_color()),
 71	mLabelWidth(p.label_width),
 72	mLabelHeight(p.label_height)
 73{	
 74	LLTextBox::Params tp = p.caption_text;
 75	// use custom label height if it is provided
 76	mLabelHeight = mLabelHeight != -1 ? mLabelHeight : BTN_HEIGHT_SMALL;
 77	// label_width is specified, not -1
 78	if(mLabelWidth!= -1)
 79	{
 80		tp.rect(LLRect( 0, mLabelHeight, mLabelWidth, 0 ));
 81	}
 82	else
 83	{
 84		tp.rect(LLRect( 0, mLabelHeight, getRect().getWidth(), 0 ));
 85	}
 86	
 87	tp.initial_value(p.label());
 88	mCaption = LLUICtrlFactory::create<LLTextBox>(tp);
 89	addChild( mCaption );
 90
 91	LLRect border_rect = getLocalRect();
 92	border_rect.mTop -= 1;
 93	border_rect.mRight -=1;
 94	border_rect.mBottom += mLabelHeight;
 95
 96	LLViewBorder::Params params = p.border;
 97	params.rect(border_rect);
 98	mBorder = LLUICtrlFactory::create<LLViewBorder> (params);
 99	addChild(mBorder);
100}
101
102LLColorSwatchCtrl::~LLColorSwatchCtrl ()
103{
104	// parent dialog is destroyed so we are too and we need to cancel selection
105	LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
106	if (pickerp)
107	{
108		pickerp->cancelSelection();
109		pickerp->closeFloater();
110	}
111}
112
113BOOL LLColorSwatchCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
114{
115	return handleMouseDown(x, y, mask);
116}
117
118BOOL LLColorSwatchCtrl::handleHover(S32 x, S32 y, MASK mask)
119{
120	getWindow()->setCursor(UI_CURSOR_HAND);
121	return TRUE;
122}
123
124BOOL LLColorSwatchCtrl::handleUnicodeCharHere(llwchar uni_char)
125{
126	if( ' ' == uni_char )
127	{
128		showPicker(TRUE);
129	}
130	return LLUICtrl::handleUnicodeCharHere(uni_char);
131}
132
133// forces color of this swatch and any associated floater to the input value, if currently invalid
134void LLColorSwatchCtrl::setOriginal(const LLColor4& color)
135{
136	mColor = color;
137	LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
138	if (pickerp)
139	{
140		pickerp->setOrigRgb(mColor.mV[VRED], mColor.mV[VGREEN], mColor.mV[VBLUE]);
141	}
142}
143
144void LLColorSwatchCtrl::set(const LLColor4& color, BOOL update_picker, BOOL from_event)
145{
146	mColor = color; 
147	LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
148	if (pickerp && update_picker)
149	{
150		pickerp->setCurRgb(mColor.mV[VRED], mColor.mV[VGREEN], mColor.mV[VBLUE]);
151	}
152	if (!from_event)
153	{
154		setControlValue(mColor.getValue());
155	}
156}
157
158void LLColorSwatchCtrl::setLabel(const std::string& label)
159{
160	mCaption->setText(label);
161}
162
163BOOL LLColorSwatchCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
164{
165	// Route future Mouse messages here preemptively.  (Release on mouse up.)
166	// No handler is needed for capture lost since this object has no state that depends on it.
167	gFocusMgr.setMouseCapture( this );
168
169	return TRUE;
170}
171
172
173BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
174{
175	// We only handle the click if the click both started and ended within us
176	if( hasMouseCapture() )
177	{
178		// Release the mouse
179		gFocusMgr.setMouseCapture( NULL );
180
181		// If mouseup in the widget, it's been clicked
182		if ( pointInView(x, y) )
183		{
184			llassert(getEnabled());
185			llassert(getVisible());
186
187			// Focus the widget now in order to return the focus
188			// after the color picker is closed.
189			setFocus(TRUE);
190
191			showPicker(FALSE);
192		}
193	}
194
195	return TRUE;
196}
197
198// assumes GL state is set for 2D
199void LLColorSwatchCtrl::draw()
200{
201	// If we're in a focused floater, don't apply the floater's alpha to the color swatch (STORM-676).
202	F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
203
204	mBorder->setKeyboardFocusHighlight(hasFocus());
205	// Draw border
206	LLRect border( 0, getRect().getHeight(), getRect().getWidth(), mLabelHeight );
207	gl_rect_2d( border, mBorderColor.get(), FALSE );
208
209	LLRect interior = border;
210	interior.stretch( -1 );
211
212	// Check state
213	if ( mValid )
214	{
215		if (!mColor.isOpaque())
216		{
217			// Draw checker board.
218			gl_rect_2d_checkerboard(interior, alpha);
219		}
220
221		// Draw the color swatch
222		gl_rect_2d(interior, mColor % alpha, TRUE);
223
224		if (!mColor.isOpaque())
225		{
226			// Draw semi-transparent center area in filled with mColor.
227			LLColor4 opaque_color = mColor;
228			opaque_color.mV[VALPHA] = alpha;
229			gGL.color4fv(opaque_color.mV);
230			if (mAlphaGradientImage.notNull())
231			{
232				gGL.pushMatrix();
233				{
234					mAlphaGradientImage->draw(interior, mColor % alpha);
235				}
236				gGL.popMatrix();
237			}
238		}
239	}
240	else
241	{
242		if (!mFallbackImageName.empty())
243		{
244			LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE, 
245				LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
246			if( fallback_image->getComponents() == 4 )
247			{	
248				gl_rect_2d_checkerboard( interior );
249			}	
250			gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), fallback_image, LLColor4::white % alpha);
251			fallback_image->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
252		}
253		else
254		{
255			// Draw grey and an X
256			gl_rect_2d(interior, LLColor4::grey % alpha, TRUE);
257			
258			gl_draw_x(interior, LLColor4::black % alpha);
259		}
260	}
261
262	LLUICtrl::draw();
263}
264
265void LLColorSwatchCtrl::setEnabled( BOOL enabled )
266{
267	mCaption->setEnabled( enabled );
268	LLView::setEnabled( enabled );
269
270	if (!enabled)
271	{
272		LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
273		if (pickerp)
274		{
275			pickerp->cancelSelection();
276			pickerp->closeFloater();
277		}
278	}
279}
280
281
282void LLColorSwatchCtrl::setValue(const LLSD& value)
283{
284	set(LLColor4(value), TRUE, TRUE);
285}
286
287//////////////////////////////////////////////////////////////////////////////
288// called (infrequently) when the color changes so the subject of the swatch can be updated.
289void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
290{
291	LLColorSwatchCtrl* subject = ( LLColorSwatchCtrl* )data;
292	if ( subject )
293	{
294		LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)subject->mPickerHandle.get();
295		if (pickerp)
296		{
297			// move color across from selector to internal widget storage
298			LLColor4 updatedColor ( pickerp->getCurR (), 
299									pickerp->getCurG (), 
300									pickerp->getCurB (), 
301									subject->mColor.mV[VALPHA] ); // keep current alpha
302			subject->mColor = updatedColor;
303			subject->setControlValue(updatedColor.getValue());
304
305			if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback)
306			{
307				subject->mOnCancelCallback( subject, LLSD());
308			}
309			else if (pick_op == COLOR_SELECT && subject->mOnSelectCallback)
310			{
311				subject->mOnSelectCallback( subject, LLSD() );
312			}
313			else
314			{
315				// just commit change
316				subject->onCommit ();
317			}
318		}
319	}
320}
321
322// This is called when the main floatercustomize panel is closed.
323// Since this class has pointers up to its parents, we need to cleanup
324// this class first in order to avoid a crash.
325void LLColorSwatchCtrl::closeFloaterColorPicker()
326{
327	LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
328	if (pickerp)
329	{
330		pickerp->setSwatch(NULL);
331		pickerp->closeFloater();
332	}
333
334	mPickerHandle.markDead();
335}
336
337void LLColorSwatchCtrl::setValid(BOOL valid )
338{
339	mValid = valid;
340
341	LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
342	if (pickerp)
343	{
344		pickerp->setActive(valid);
345	}
346}
347
348void LLColorSwatchCtrl::showPicker(BOOL take_focus)
349{
350	LLFloaterColorPicker* pickerp = (LLFloaterColorPicker*)mPickerHandle.get();
351	if (!pickerp)
352	{
353		pickerp = new LLFloaterColorPicker(this, mCanApplyImmediately);
354		LLFloater* parent = gFloaterView->getParentFloater(this);
355		if (parent)
356		{
357			parent->addDependentFloater(pickerp);
358		}
359		mPickerHandle = pickerp->getHandle();
360	}
361
362	// initialize picker with current color
363	pickerp->initUI ( mColor.mV [ VRED ], mColor.mV [ VGREEN ], mColor.mV [ VBLUE ] );
364
365	// display it
366	pickerp->showUI ();
367
368	if (take_focus)
369	{
370		pickerp->setFocus(TRUE);
371	}
372}
373