PageRenderTime 33ms CodeModel.GetById 2ms app.highlight 26ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/newview/llinventorylistitem.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 463 lines | 363 code | 61 blank | 39 comment | 40 complexity | 1af445cad04a6b200ef4e4b1bc8d37d9 MD5 | raw file
  1/**
  2 * @file llinventorylistitem.cpp
  3 * @brief Inventory list item panel.
  4 *
  5 * Class LLPanelInventoryListItemBase displays inventory item as an element
  6 * of LLInventoryItemsList.
  7 *
  8 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
  9 * Second Life Viewer Source Code
 10 * Copyright (C) 2010, Linden Research, Inc.
 11 * 
 12 * This library is free software; you can redistribute it and/or
 13 * modify it under the terms of the GNU Lesser General Public
 14 * License as published by the Free Software Foundation;
 15 * version 2.1 of the License only.
 16 * 
 17 * This library is distributed in the hope that it will be useful,
 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 20 * Lesser General Public License for more details.
 21 * 
 22 * You should have received a copy of the GNU Lesser General Public
 23 * License along with this library; if not, write to the Free Software
 24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 25 * 
 26 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 27 * $/LicenseInfo$
 28 */
 29
 30#include "llviewerprecompiledheaders.h"
 31
 32#include "llinventorylistitem.h"
 33
 34// llui
 35#include "lliconctrl.h"
 36#include "lltextbox.h"
 37#include "lltextutil.h"
 38
 39// newview
 40#include "llinventorymodel.h"
 41#include "llviewerinventory.h"
 42
 43static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item");
 44
 45static const S32 WIDGET_SPACING = 3;
 46
 47LLPanelInventoryListItemBase::Params::Params()
 48:	default_style("default_style"),
 49	worn_style("worn_style"),
 50	hover_image("hover_image"),
 51	selected_image("selected_image"),
 52	separator_image("separator_image"),
 53	item_icon("item_icon"),
 54	item_name("item_name")
 55{};
 56
 57LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item)
 58{
 59	LLPanelInventoryListItemBase* list_item = NULL;
 60	if (item)
 61	{
 62		const LLPanelInventoryListItemBase::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelInventoryListItemBase>();
 63		list_item = new LLPanelInventoryListItemBase(item, params);
 64		list_item->initFromParams(params);
 65		list_item->postBuild();
 66	}
 67	return list_item;
 68}
 69
 70void LLPanelInventoryListItemBase::draw()
 71{
 72	if (getNeedsRefresh())
 73	{
 74		LLViewerInventoryItem* inv_item = getItem();
 75		if (inv_item)
 76		{
 77			updateItem(inv_item->getName());
 78		}
 79		setNeedsRefresh(false);
 80	}
 81
 82	if (mHovered && mHoverImage)
 83	{
 84		mHoverImage->draw(getLocalRect());
 85	}
 86
 87	if (mSelected && mSelectedImage)
 88	{
 89		mSelectedImage->draw(getLocalRect());
 90	}
 91
 92	if (mSeparatorVisible && mSeparatorImage)
 93	{
 94		// place under bottom of listitem, using image height
 95		// item_pad in list using the item should be >= image height
 96		// to avoid cropping of top of the next item.
 97		LLRect separator_rect = getLocalRect();
 98		separator_rect.mTop = separator_rect.mBottom;
 99		separator_rect.mBottom -= mSeparatorImage->getHeight();
100		F32 alpha = getCurrentTransparency();
101		mSeparatorImage->draw(separator_rect, UI_VERTEX_COLOR % alpha);
102	}
103	
104	LLPanel::draw();
105}
106
107// virtual
108void LLPanelInventoryListItemBase::updateItem(const std::string& name,
109											  EItemState item_state)
110{
111	setIconImage(mIconImage);
112	setTitle(name, mHighlightedText, item_state);
113}
114
115void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
116{
117	LLUICtrl* ctrl = findChild<LLUICtrl>(name);
118	if(ctrl)
119	{
120		addWidgetToLeftSide(ctrl, show_widget);
121	}
122}
123
124void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
125{
126	mLeftSideWidgets.push_back(ctrl);
127	setShowWidget(ctrl, show_widget);
128}
129
130void LLPanelInventoryListItemBase::addWidgetToRightSide(const std::string& name, bool show_widget/* = true*/)
131{
132	LLUICtrl* ctrl = findChild<LLUICtrl>(name);
133	if(ctrl)
134	{
135		addWidgetToRightSide(ctrl, show_widget);
136	}
137}
138
139void LLPanelInventoryListItemBase::addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
140{
141	mRightSideWidgets.push_back(ctrl);
142	setShowWidget(ctrl, show_widget);
143}
144
145void LLPanelInventoryListItemBase::setShowWidget(const std::string& name, bool show)
146{
147	LLUICtrl* widget = findChild<LLUICtrl>(name);
148	if(widget)
149	{
150		setShowWidget(widget, show);
151	}
152}
153
154void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show)
155{
156	// Enable state determines whether widget may become visible in setWidgetsVisible()
157	ctrl->setEnabled(show);
158}
159
160BOOL LLPanelInventoryListItemBase::postBuild()
161{
162	LLViewerInventoryItem* inv_item = getItem();
163	if (inv_item)
164	{
165		mIconImage = LLInventoryIcon::getIcon(inv_item->getType(), inv_item->getInventoryType(), inv_item->getFlags(), FALSE);
166		updateItem(inv_item->getName());
167	}
168
169	setNeedsRefresh(true);
170
171	setWidgetsVisible(false);
172	reshapeWidgets();
173
174	return TRUE;
175}
176
177void LLPanelInventoryListItemBase::setValue(const LLSD& value)
178{
179	if (!value.isMap()) return;
180	if (!value.has("selected")) return;
181	mSelected = value["selected"];
182}
183
184void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
185{
186	mHovered = true;
187	LLPanel::onMouseEnter(x, y, mask);
188}
189
190void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
191{
192	mHovered = false;
193	LLPanel::onMouseLeave(x, y, mask);
194}
195
196const std::string& LLPanelInventoryListItemBase::getItemName() const
197{
198	LLViewerInventoryItem* inv_item = getItem();
199	if (NULL == inv_item)
200	{
201		return LLStringUtil::null;
202	}
203	return inv_item->getName();
204}
205
206LLAssetType::EType LLPanelInventoryListItemBase::getType() const
207{
208	LLViewerInventoryItem* inv_item = getItem();
209	if (NULL == inv_item)
210	{
211		return LLAssetType::AT_NONE;
212	}
213	return inv_item->getType();
214}
215
216LLWearableType::EType LLPanelInventoryListItemBase::getWearableType() const
217{
218	LLViewerInventoryItem* inv_item = getItem();
219	if (NULL == inv_item)
220	{
221		return LLWearableType::WT_NONE;
222	}
223	return inv_item->getWearableType();
224}
225
226const std::string& LLPanelInventoryListItemBase::getDescription() const
227{
228	LLViewerInventoryItem* inv_item = getItem();
229	if (NULL == inv_item)
230	{
231		return LLStringUtil::null;
232	}
233	return inv_item->getDescription();
234}
235
236time_t LLPanelInventoryListItemBase::getCreationDate() const
237{
238	LLViewerInventoryItem* inv_item = getItem();
239	if (NULL == inv_item)
240	{
241		return 0;
242	}
243
244	return inv_item->getCreationDate();
245}
246
247LLViewerInventoryItem* LLPanelInventoryListItemBase::getItem() const
248{
249	return gInventory.getItem(mInventoryItemUUID);
250}
251
252S32 LLPanelInventoryListItemBase::notify(const LLSD& info)
253{
254	S32 rv = 0;
255	if(info.has("match_filter"))
256	{
257		mHighlightedText = info["match_filter"].asString();
258
259		std::string test(mTitleCtrl->getText());
260		LLStringUtil::toUpper(test);
261
262		if(mHighlightedText.empty() || std::string::npos != test.find(mHighlightedText))
263		{
264			rv = 0; // substring is found
265		}
266		else
267		{
268			rv = -1;
269		}
270
271		setNeedsRefresh(true);
272	}
273	else
274	{
275		rv = LLPanel::notify(info);
276	}
277	return rv;
278}
279
280LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item, const LLPanelInventoryListItemBase::Params& params)
281:	LLPanel(params),
282	mInventoryItemUUID(item ? item->getUUID() : LLUUID::null),
283	mIconCtrl(NULL),
284	mTitleCtrl(NULL),
285	mWidgetSpacing(WIDGET_SPACING),
286	mLeftWidgetsWidth(0),
287	mRightWidgetsWidth(0),
288	mNeedsRefresh(false),
289	mHovered(false),
290	mSelected(false),
291	mSeparatorVisible(false),
292	mHoverImage(params.hover_image),
293	mSelectedImage(params.selected_image),
294	mSeparatorImage(params.separator_image)
295{
296	LLIconCtrl::Params icon_params(params.item_icon);
297	applyXUILayout(icon_params, this);
298
299	mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
300	if (mIconCtrl)
301	{
302		addChild(mIconCtrl);
303	}
304	else
305	{
306		LLIconCtrl::Params icon_params;
307		icon_params.name = "item_icon";
308		mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
309	}
310
311	LLTextBox::Params text_params(params.item_name);
312	applyXUILayout(text_params, this);
313
314	mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params);
315	if (mTitleCtrl)
316	{
317		addChild(mTitleCtrl);
318	}
319	else
320	{
321		LLTextBox::Params text_aprams;
322		text_params.name = "item_title";
323		mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params);
324	}
325}
326
327class WidgetVisibilityChanger
328{
329public:
330	WidgetVisibilityChanger(bool visible) : mVisible(visible){}
331	void operator()(LLUICtrl* widget)
332	{
333		// Disabled widgets never become visible. see LLPanelInventoryListItemBase::setShowWidget()
334		widget->setVisible(mVisible && widget->getEnabled());
335	}
336private:
337	bool mVisible;
338};
339
340void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible)
341{
342	std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible));
343	std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible));
344}
345
346void LLPanelInventoryListItemBase::reshapeWidgets()
347{
348	// disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem
349	/*reshapeLeftWidgets();*/
350	reshapeRightWidgets();
351	reshapeMiddleWidgets();
352}
353
354void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image)
355{
356	if(image)
357	{
358		mIconImage = image; 
359		mIconCtrl->setImage(mIconImage);
360	}
361}
362
363void LLPanelInventoryListItemBase::setTitle(const std::string& title,
364											const std::string& highlit_text,
365											EItemState item_state)
366{
367	mTitleCtrl->setToolTip(title);
368
369	LLStyle::Params style_params;
370
371	const LLPanelInventoryListItemBase::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelInventoryListItemBase>();
372
373	switch(item_state)
374	{
375	case IS_DEFAULT:
376		style_params = params.default_style();
377		break;
378	case IS_WORN:
379		style_params = params.worn_style();
380		break;
381	default:;
382	}
383
384	LLTextUtil::textboxSetHighlightedVal(
385		mTitleCtrl,
386		style_params,
387		title,
388		highlit_text);
389}
390
391BOOL LLPanelInventoryListItemBase::handleToolTip( S32 x, S32 y, MASK mask)
392{
393	LLRect text_box_rect = mTitleCtrl->getRect();
394	if (text_box_rect.pointInRect(x, y) &&
395		mTitleCtrl->getTextPixelWidth() <= text_box_rect.getWidth())
396	{
397		return FALSE;
398	}
399	return LLPanel::handleToolTip(x, y, mask);
400}
401
402void LLPanelInventoryListItemBase::reshapeLeftWidgets()
403{
404	S32 widget_left = 0;
405	mLeftWidgetsWidth = 0;
406
407	widget_array_t::const_iterator it = mLeftSideWidgets.begin();
408	const widget_array_t::const_iterator it_end = mLeftSideWidgets.end();
409	for( ; it_end != it; ++it)
410	{
411		LLUICtrl* widget = *it;
412		if(!widget->getVisible())
413		{
414			continue;
415		}
416		LLRect widget_rect(widget->getRect());
417		widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
418		widget->setShape(widget_rect);
419
420		widget_left += widget_rect.getWidth() + getWidgetSpacing();
421		mLeftWidgetsWidth = widget_rect.mRight;
422	}
423}
424
425void LLPanelInventoryListItemBase::reshapeRightWidgets()
426{
427	S32 widget_right = getLocalRect().getWidth();
428	S32 widget_left = widget_right;
429
430	widget_array_t::const_reverse_iterator it = mRightSideWidgets.rbegin();
431	const widget_array_t::const_reverse_iterator it_end = mRightSideWidgets.rend();
432	for( ; it_end != it; ++it)
433	{
434		LLUICtrl* widget = *it;
435		if(!widget->getVisible())
436		{
437			continue;
438		}
439		LLRect widget_rect(widget->getRect());
440		widget_left = widget_right - widget_rect.getWidth();
441		widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
442		widget->setShape(widget_rect);
443
444		widget_right = widget_left - getWidgetSpacing();
445	}
446	mRightWidgetsWidth = getLocalRect().getWidth() - widget_left;
447}
448
449void LLPanelInventoryListItemBase::reshapeMiddleWidgets()
450{
451	LLRect icon_rect(mIconCtrl->getRect());
452	icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop, 
453		icon_rect.getWidth(), icon_rect.getHeight());
454	mIconCtrl->setShape(icon_rect);
455
456	S32 name_left = icon_rect.mRight + getWidgetSpacing();
457	S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
458	LLRect name_rect(mTitleCtrl->getRect());
459	name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
460	mTitleCtrl->setShape(name_rect);
461}
462
463// EOF