merge from viewer-trunk
commit
fee6f311d3
|
|
@ -1338,7 +1338,7 @@ LLImageFormatted::LLImageFormatted(S8 codec)
|
|||
mCodec(codec),
|
||||
mDecoding(0),
|
||||
mDecoded(0),
|
||||
mDiscardLevel(0)
|
||||
mDiscardLevel(-1)
|
||||
{
|
||||
mMemType = LLMemType::MTYPE_IMAGEFORMATTED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ void LLPluginClassMedia::idle(void)
|
|||
mPlugin->idle();
|
||||
}
|
||||
|
||||
if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL))
|
||||
if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()))
|
||||
{
|
||||
// Can't process a size change at this time
|
||||
}
|
||||
|
|
@ -437,6 +437,12 @@ void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int
|
|||
{
|
||||
if(type == MOUSE_EVENT_MOVE)
|
||||
{
|
||||
if(!mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked())
|
||||
{
|
||||
// Don't queue up mouse move events that can't be delivered.
|
||||
return;
|
||||
}
|
||||
|
||||
if((x == mLastMouseX) && (y == mLastMouseY))
|
||||
{
|
||||
// Don't spam unnecessary mouse move events.
|
||||
|
|
|
|||
|
|
@ -299,26 +299,23 @@ bool LLPluginMessagePipe::pump(F64 timeout)
|
|||
void LLPluginMessagePipe::processInput(void)
|
||||
{
|
||||
// Look for input delimiter(s) in the input buffer.
|
||||
int start = 0;
|
||||
int delim;
|
||||
while((delim = mInput.find(MESSAGE_DELIMITER, start)) != std::string::npos)
|
||||
while((delim = mInput.find(MESSAGE_DELIMITER)) != std::string::npos)
|
||||
{
|
||||
// Let the owner process this message
|
||||
if (mOwner)
|
||||
{
|
||||
mOwner->receiveMessageRaw(mInput.substr(start, delim - start));
|
||||
// Pull the message out of the input buffer before calling receiveMessageRaw.
|
||||
// It's now possible for this function to get called recursively (in the case where the plugin makes a blocking request)
|
||||
// and this guarantees that the messages will get dequeued correctly.
|
||||
std::string message(mInput, 0, delim);
|
||||
mInput.erase(0, delim + 1);
|
||||
mOwner->receiveMessageRaw(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Plugin") << "!mOwner" << LL_ENDL;
|
||||
}
|
||||
|
||||
start = delim + 1;
|
||||
}
|
||||
|
||||
// Remove delivered messages from the input buffer.
|
||||
if(start != 0)
|
||||
mInput = mInput.substr(start);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ LLPluginProcessChild::LLPluginProcessChild()
|
|||
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
|
||||
mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz
|
||||
mCPUElapsed = 0.0f;
|
||||
mBlockingRequest = false;
|
||||
mBlockingResponseReceived = false;
|
||||
}
|
||||
|
||||
LLPluginProcessChild::~LLPluginProcessChild()
|
||||
|
|
@ -226,6 +228,7 @@ void LLPluginProcessChild::idle(void)
|
|||
|
||||
void LLPluginProcessChild::sleep(F64 seconds)
|
||||
{
|
||||
deliverQueuedMessages();
|
||||
if(mMessagePipe)
|
||||
{
|
||||
mMessagePipe->pump(seconds);
|
||||
|
|
@ -238,6 +241,7 @@ void LLPluginProcessChild::sleep(F64 seconds)
|
|||
|
||||
void LLPluginProcessChild::pump(void)
|
||||
{
|
||||
deliverQueuedMessages();
|
||||
if(mMessagePipe)
|
||||
{
|
||||
mMessagePipe->pump(0.0f);
|
||||
|
|
@ -309,15 +313,32 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
|
|||
|
||||
LL_DEBUGS("Plugin") << "Received from parent: " << message << LL_ENDL;
|
||||
|
||||
// Decode this message
|
||||
LLPluginMessage parsed;
|
||||
parsed.parse(message);
|
||||
|
||||
if(mBlockingRequest)
|
||||
{
|
||||
// We're blocking the plugin waiting for a response.
|
||||
|
||||
if(parsed.hasValue("blocking_response"))
|
||||
{
|
||||
// This is the message we've been waiting for -- fall through and send it immediately.
|
||||
mBlockingResponseReceived = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Still waiting. Queue this message and don't process it yet.
|
||||
mMessageQueue.push(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool passMessage = true;
|
||||
|
||||
// FIXME: how should we handle queueing here?
|
||||
|
||||
{
|
||||
// Decode this message
|
||||
LLPluginMessage parsed;
|
||||
parsed.parse(message);
|
||||
|
||||
std::string message_class = parsed.getClass();
|
||||
if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
|
||||
{
|
||||
|
|
@ -425,7 +446,13 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
|
|||
void LLPluginProcessChild::receivePluginMessage(const std::string &message)
|
||||
{
|
||||
LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL;
|
||||
|
||||
|
||||
if(mBlockingRequest)
|
||||
{
|
||||
//
|
||||
LL_ERRS("Plugin") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL;
|
||||
}
|
||||
|
||||
// Incoming message from the plugin instance
|
||||
bool passMessage = true;
|
||||
|
||||
|
|
@ -436,6 +463,12 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
|
|||
// Decode this message
|
||||
LLPluginMessage parsed;
|
||||
parsed.parse(message);
|
||||
|
||||
if(parsed.hasValue("blocking_request"))
|
||||
{
|
||||
mBlockingRequest = true;
|
||||
}
|
||||
|
||||
std::string message_class = parsed.getClass();
|
||||
if(message_class == "base")
|
||||
{
|
||||
|
|
@ -494,6 +527,19 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
|
|||
LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
|
||||
writeMessageRaw(message);
|
||||
}
|
||||
|
||||
while(mBlockingRequest)
|
||||
{
|
||||
// The plugin wants to block and wait for a response to this message.
|
||||
sleep(mSleepTime); // this will pump the message pipe and process messages
|
||||
|
||||
if(mBlockingResponseReceived || mSocketError != APR_SUCCESS || (mMessagePipe == NULL))
|
||||
{
|
||||
// Response has been received, or we've hit an error state. Stop waiting.
|
||||
mBlockingRequest = false;
|
||||
mBlockingResponseReceived = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -502,3 +548,15 @@ void LLPluginProcessChild::setState(EState state)
|
|||
LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL;
|
||||
mState = state;
|
||||
};
|
||||
|
||||
void LLPluginProcessChild::deliverQueuedMessages()
|
||||
{
|
||||
if(!mBlockingRequest)
|
||||
{
|
||||
while(!mMessageQueue.empty())
|
||||
{
|
||||
receiveMessageRaw(mMessageQueue.front());
|
||||
mMessageQueue.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,11 @@ private:
|
|||
LLTimer mHeartbeat;
|
||||
F64 mSleepTime;
|
||||
F64 mCPUElapsed;
|
||||
bool mBlockingRequest;
|
||||
bool mBlockingResponseReceived;
|
||||
std::queue<std::string> mMessageQueue;
|
||||
|
||||
void deliverQueuedMessages();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
|
|||
mCPUUsage = 0.0;
|
||||
mDisableTimeout = false;
|
||||
mDebug = false;
|
||||
mBlocked = false;
|
||||
|
||||
mPluginLaunchTimeout = 60.0f;
|
||||
mPluginLockupTimeout = 15.0f;
|
||||
|
|
@ -479,6 +480,13 @@ void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send)
|
|||
|
||||
void LLPluginProcessParent::sendMessage(const LLPluginMessage &message)
|
||||
{
|
||||
if(message.hasValue("blocking_response"))
|
||||
{
|
||||
mBlocked = false;
|
||||
|
||||
// reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked.
|
||||
mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
|
||||
}
|
||||
|
||||
std::string buffer = message.generate();
|
||||
LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL;
|
||||
|
|
@ -501,6 +509,11 @@ void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
|
|||
|
||||
void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
|
||||
{
|
||||
if(message.hasValue("blocking_request"))
|
||||
{
|
||||
mBlocked = true;
|
||||
}
|
||||
|
||||
std::string message_class = message.getClass();
|
||||
if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
|
||||
{
|
||||
|
|
@ -689,18 +702,15 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit()
|
|||
{
|
||||
bool result = false;
|
||||
|
||||
if(!mDisableTimeout && !mDebug)
|
||||
if(!mProcess.isRunning())
|
||||
{
|
||||
if(!mProcess.isRunning())
|
||||
{
|
||||
LL_WARNS("Plugin") << "child exited" << llendl;
|
||||
result = true;
|
||||
}
|
||||
else if(pluginLockedUp())
|
||||
{
|
||||
LL_WARNS("Plugin") << "timeout" << llendl;
|
||||
result = true;
|
||||
}
|
||||
LL_WARNS("Plugin") << "child exited" << llendl;
|
||||
result = true;
|
||||
}
|
||||
else if(pluginLockedUp())
|
||||
{
|
||||
LL_WARNS("Plugin") << "timeout" << llendl;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -708,6 +718,12 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit()
|
|||
|
||||
bool LLPluginProcessParent::pluginLockedUp()
|
||||
{
|
||||
if(mDisableTimeout || mDebug || mBlocked)
|
||||
{
|
||||
// Never time out a plugin process in these cases.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the timer is running and has expired, the plugin has locked up.
|
||||
return (mHeartbeat.getStarted() && mHeartbeat.hasExpired());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ public:
|
|||
// returns true if the process has exited or we've had a fatal error
|
||||
bool isDone(void);
|
||||
|
||||
// returns true if the process is currently waiting on a blocking request
|
||||
bool isBlocked(void) { return mBlocked; };
|
||||
|
||||
void killSockets(void);
|
||||
|
||||
// Go to the proper error state
|
||||
|
|
@ -160,6 +163,7 @@ private:
|
|||
|
||||
bool mDisableTimeout;
|
||||
bool mDebug;
|
||||
bool mBlocked;
|
||||
|
||||
LLProcessLauncher mDebugger;
|
||||
|
||||
|
|
|
|||
|
|
@ -457,3 +457,8 @@ BOOL LLSpinCtrl::handleKeyHere(KEY key, MASK mask)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLSpinCtrl::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
// just treat a double click as a second click
|
||||
return handleMouseDown(x, y, mask);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ public:
|
|||
|
||||
virtual BOOL handleScrollWheel(S32 x,S32 y,S32 clicks);
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
||||
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
|
||||
|
||||
void onEditorCommit(const LLSD& data);
|
||||
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
|
||||
|
|
|
|||
|
|
@ -5849,7 +5849,18 @@
|
|||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>RecentItemsSortOrder</key>
|
||||
<key>MediaRollOffFactor</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Multiplier to change rate of media attenuation</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>10.0</real>
|
||||
</map>
|
||||
<key>RecentItemsSortOrder</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifies sort key for recent inventory items (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)</string>
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ void LLCOFWearables::onSelectionChange(LLFlatListView* selected_list)
|
|||
onCommit();
|
||||
}
|
||||
|
||||
#include "llwearableitemslist.h"
|
||||
void LLCOFWearables::refresh()
|
||||
{
|
||||
clear();
|
||||
|
|
@ -117,16 +118,15 @@ void LLCOFWearables::populateAttachmentsAndBodypartsLists(const LLInventoryModel
|
|||
|
||||
const LLAssetType::EType item_type = item->getType();
|
||||
if (item_type == LLAssetType::AT_CLOTHING) continue;
|
||||
|
||||
LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item);
|
||||
if (!item_panel) continue;
|
||||
|
||||
LLPanelInventoryListItemBase* item_panel = NULL;
|
||||
if (item_type == LLAssetType::AT_OBJECT)
|
||||
{
|
||||
item_panel = LLPanelInventoryListItemBase::create(item);
|
||||
mAttachments->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
|
||||
}
|
||||
else if (item_type == LLAssetType::AT_BODYPART)
|
||||
{
|
||||
item_panel = LLPanelBodyPartsListItem::create(item);
|
||||
mBodyParts->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
|
||||
addWearableTypeSeparator(mBodyParts);
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ void LLCOFWearables::populateClothingList(LLAppearanceMgr::wearables_by_type_t&
|
|||
{
|
||||
LLViewerInventoryItem* item = clothing_by_type[type][i];
|
||||
|
||||
LLPanelInventoryListItem* item_panel = LLPanelInventoryListItem::createItemPanel(item);
|
||||
LLPanelInventoryListItemBase* item_panel = LLPanelClothingListItem::create(item);
|
||||
if (!item_panel) continue;
|
||||
|
||||
mClothing->addItem(item_panel, item->getUUID(), ADD_BOTTOM, false);
|
||||
|
|
|
|||
|
|
@ -50,42 +50,20 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
LLPanelInventoryListItem* LLPanelInventoryListItem::createItemPanel(const LLViewerInventoryItem* item)
|
||||
static const S32 WIDGET_SPACING = 3;
|
||||
|
||||
LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInventoryItem* item)
|
||||
{
|
||||
LLPanelInventoryListItemBase* list_item = NULL;
|
||||
if (item)
|
||||
{
|
||||
return new LLPanelInventoryListItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
list_item = new LLPanelInventoryListItemBase(item);
|
||||
list_item->init();
|
||||
}
|
||||
return list_item;
|
||||
}
|
||||
|
||||
LLPanelInventoryListItem::~LLPanelInventoryListItem()
|
||||
{}
|
||||
|
||||
//virtual
|
||||
BOOL LLPanelInventoryListItem::postBuild()
|
||||
{
|
||||
mIcon = getChild<LLIconCtrl>("item_icon");
|
||||
mTitle = getChild<LLTextBox>("item_name");
|
||||
|
||||
updateItem();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLPanelInventoryListItem::setValue(const LLSD& value)
|
||||
{
|
||||
if (!value.isMap()) return;
|
||||
if (!value.has("selected")) return;
|
||||
childSetVisible("selected_icon", value["selected"]);
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItem::updateItem()
|
||||
void LLPanelInventoryListItemBase::updateItem()
|
||||
{
|
||||
if (mItemIcon.notNull())
|
||||
mIcon->setImage(mItemIcon);
|
||||
|
|
@ -93,35 +71,193 @@ void LLPanelInventoryListItem::updateItem()
|
|||
LLTextUtil::textboxSetHighlightedVal(
|
||||
mTitle,
|
||||
LLStyle::Params(),
|
||||
mItemName,
|
||||
mItem->getName(),
|
||||
mHighlightedText);
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItem::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
|
||||
{
|
||||
LLUICtrl* ctrl = findChild<LLUICtrl>(name);
|
||||
if(ctrl)
|
||||
{
|
||||
addWidgetToLeftSide(ctrl, show_widget);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
|
||||
{
|
||||
mLeftSideWidgets.push_back(ctrl);
|
||||
setShowWidget(ctrl, show_widget);
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::addWidgetToRightSide(const std::string& name, bool show_widget/* = true*/)
|
||||
{
|
||||
LLUICtrl* ctrl = findChild<LLUICtrl>(name);
|
||||
if(ctrl)
|
||||
{
|
||||
addWidgetToRightSide(ctrl, show_widget);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget/* = true*/)
|
||||
{
|
||||
mRightSideWidgets.push_back(ctrl);
|
||||
setShowWidget(ctrl, show_widget);
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::setShowWidget(const std::string& name, bool show)
|
||||
{
|
||||
LLUICtrl* widget = findChild<LLUICtrl>(name);
|
||||
if(widget)
|
||||
{
|
||||
setShowWidget(widget, show);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show)
|
||||
{
|
||||
// Enable state determines whether widget may become visible in setWidgetsVisible()
|
||||
ctrl->setEnabled(show);
|
||||
}
|
||||
|
||||
BOOL LLPanelInventoryListItemBase::postBuild()
|
||||
{
|
||||
// Inheritors need to call base implementation
|
||||
mIcon = getChild<LLIconCtrl>("item_icon");
|
||||
mTitle = getChild<LLTextBox>("item_name");
|
||||
|
||||
updateItem();
|
||||
|
||||
setWidgetsVisible(false);
|
||||
reshapeWidgets();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::setValue(const LLSD& value)
|
||||
{
|
||||
if (!value.isMap()) return;
|
||||
if (!value.has("selected")) return;
|
||||
childSetVisible("selected_icon", value["selected"]);
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
childSetVisible("hovered_icon", true);
|
||||
|
||||
LLPanel::onMouseEnter(x, y, mask);
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItem::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
childSetVisible("hovered_icon", false);
|
||||
|
||||
LLPanel::onMouseLeave(x, y, mask);
|
||||
}
|
||||
|
||||
LLPanelInventoryListItem::LLPanelInventoryListItem(const LLViewerInventoryItem* item)
|
||||
: LLPanel()
|
||||
,mIcon(NULL)
|
||||
,mTitle(NULL)
|
||||
LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item)
|
||||
: LLPanel()
|
||||
, mItem(item)
|
||||
, mIcon(NULL)
|
||||
, mTitle(NULL)
|
||||
, mWidgetSpacing(WIDGET_SPACING)
|
||||
, mLeftWidgetsWidth(0)
|
||||
, mRightWidgetsWidth(0)
|
||||
{
|
||||
mItemName = item->getName();
|
||||
mItemIcon = get_item_icon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE);
|
||||
mItemIcon = get_item_icon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::init()
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
|
||||
}
|
||||
|
||||
class WidgetVisibilityChanger
|
||||
{
|
||||
public:
|
||||
WidgetVisibilityChanger(bool visible) : mVisible(visible){}
|
||||
void operator()(LLUICtrl* widget)
|
||||
{
|
||||
// Disabled widgets never become visible. see LLPanelInventoryListItemBase::setShowWidget()
|
||||
widget->setVisible(mVisible && widget->getEnabled());
|
||||
}
|
||||
private:
|
||||
bool mVisible;
|
||||
};
|
||||
|
||||
void LLPanelInventoryListItemBase::setWidgetsVisible(bool visible)
|
||||
{
|
||||
std::for_each(mLeftSideWidgets.begin(), mLeftSideWidgets.end(), WidgetVisibilityChanger(visible));
|
||||
std::for_each(mRightSideWidgets.begin(), mRightSideWidgets.end(), WidgetVisibilityChanger(visible));
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::reshapeWidgets()
|
||||
{
|
||||
// disabled reshape left for now to reserve space for 'delete' button in LLPanelClothingListItem
|
||||
/*reshapeLeftWidgets();*/
|
||||
reshapeRightWidgets();
|
||||
reshapeMiddleWidgets();
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::reshapeLeftWidgets()
|
||||
{
|
||||
S32 widget_left = 0;
|
||||
mLeftWidgetsWidth = 0;
|
||||
|
||||
widget_array_t::const_iterator it = mLeftSideWidgets.begin();
|
||||
const widget_array_t::const_iterator it_end = mLeftSideWidgets.end();
|
||||
for( ; it_end != it; ++it)
|
||||
{
|
||||
LLUICtrl* widget = *it;
|
||||
if(!widget->getVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
LLRect widget_rect(widget->getRect());
|
||||
widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
|
||||
widget->setShape(widget_rect);
|
||||
|
||||
widget_left += widget_rect.getWidth() + getWidgetSpacing();
|
||||
mLeftWidgetsWidth = widget_rect.mRight;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::reshapeRightWidgets()
|
||||
{
|
||||
S32 widget_right = getLocalRect().getWidth();
|
||||
S32 widget_left = widget_right;
|
||||
|
||||
widget_array_t::const_reverse_iterator it = mRightSideWidgets.rbegin();
|
||||
const widget_array_t::const_reverse_iterator it_end = mRightSideWidgets.rend();
|
||||
for( ; it_end != it; ++it)
|
||||
{
|
||||
LLUICtrl* widget = *it;
|
||||
if(!widget->getVisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
LLRect widget_rect(widget->getRect());
|
||||
widget_left = widget_right - widget_rect.getWidth();
|
||||
widget_rect.setLeftTopAndSize(widget_left, widget_rect.mTop, widget_rect.getWidth(), widget_rect.getHeight());
|
||||
widget->setShape(widget_rect);
|
||||
|
||||
widget_right = widget_left - getWidgetSpacing();
|
||||
}
|
||||
mRightWidgetsWidth = getLocalRect().getWidth() - widget_left;
|
||||
}
|
||||
|
||||
void LLPanelInventoryListItemBase::reshapeMiddleWidgets()
|
||||
{
|
||||
LLRect icon_rect(mIcon->getRect());
|
||||
icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop,
|
||||
icon_rect.getWidth(), icon_rect.getHeight());
|
||||
mIcon->setShape(icon_rect);
|
||||
|
||||
S32 name_left = icon_rect.mRight + getWidgetSpacing();
|
||||
S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
|
||||
LLRect name_rect(mTitle->getRect());
|
||||
name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
|
||||
mTitle->setShape(name_rect);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -223,7 +359,7 @@ void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item)
|
|||
llassert(!"No inventory item. Couldn't create flat list item.");
|
||||
}
|
||||
|
||||
LLPanelInventoryListItem *list_item = LLPanelInventoryListItem::createItemPanel(item);
|
||||
LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item);
|
||||
if (!list_item)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,33 +47,130 @@ class LLIconCtrl;
|
|||
class LLTextBox;
|
||||
class LLViewerInventoryItem;
|
||||
|
||||
class LLPanelInventoryListItem : public LLPanel
|
||||
/**
|
||||
* @class LLPanelInventoryListItemBase
|
||||
*
|
||||
* Base class for Inventory flat list item. Panel consists of inventory icon
|
||||
* and inventory item name.
|
||||
* This class is able to display widgets(buttons) on left(before icon) and right(after text-box) sides
|
||||
* of panel.
|
||||
*
|
||||
* How to use (see LLPanelClothingListItem for example):
|
||||
* - implement init() to build panel from xml
|
||||
* - create new xml file, fill it with widgets you want to dynamically show/hide/reshape on left/right sides
|
||||
* - redefine postBuild()(call base implementation) and add needed widgets to needed sides,
|
||||
*
|
||||
*/
|
||||
class LLPanelInventoryListItemBase : public LLPanel
|
||||
{
|
||||
public:
|
||||
static LLPanelInventoryListItem* createItemPanel(const LLViewerInventoryItem* item);
|
||||
|
||||
virtual ~LLPanelInventoryListItem();
|
||||
static LLPanelInventoryListItemBase* create(LLViewerInventoryItem* item);
|
||||
|
||||
/**
|
||||
* Called after inventory item was updated, update panel widgets to reflect inventory changes.
|
||||
*/
|
||||
virtual void updateItem();
|
||||
|
||||
/**
|
||||
* Add widget to left side
|
||||
*/
|
||||
void addWidgetToLeftSide(const std::string& name, bool show_widget = true);
|
||||
void addWidgetToLeftSide(LLUICtrl* ctrl, bool show_widget = true);
|
||||
|
||||
/**
|
||||
* Add widget to right side, widget is supposed to be child of calling panel
|
||||
*/
|
||||
void addWidgetToRightSide(const std::string& name, bool show_widget = true);
|
||||
void addWidgetToRightSide(LLUICtrl* ctrl, bool show_widget = true);
|
||||
|
||||
/**
|
||||
* Mark widgets as visible. Only visible widgets take part in reshaping children
|
||||
*/
|
||||
void setShowWidget(const std::string& name, bool show);
|
||||
void setShowWidget(LLUICtrl* ctrl, bool show);
|
||||
|
||||
/**
|
||||
* Set spacing between widgets during reshape
|
||||
*/
|
||||
void setWidgetSpacing(S32 spacing) { mWidgetSpacing = spacing; }
|
||||
|
||||
S32 getWidgetSpacing() { return mWidgetSpacing; }
|
||||
|
||||
/**
|
||||
* Inheritors need to call base implementation of postBuild()
|
||||
*/
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
/**
|
||||
* Handles item selection
|
||||
*/
|
||||
/*virtual*/ void setValue(const LLSD& value);
|
||||
|
||||
void updateItem();
|
||||
/* Highlights item */
|
||||
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
/* Removes item highlight */
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
||||
void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
virtual ~LLPanelInventoryListItemBase(){}
|
||||
|
||||
protected:
|
||||
LLPanelInventoryListItem(const LLViewerInventoryItem* item);
|
||||
|
||||
LLPanelInventoryListItemBase(LLViewerInventoryItem* item);
|
||||
|
||||
typedef std::vector<LLUICtrl*> widget_array_t;
|
||||
|
||||
/**
|
||||
* Use it from a factory function to build panel, do not build panel in constructor
|
||||
*/
|
||||
virtual void init();
|
||||
|
||||
void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; }
|
||||
void setRightWidgetsWidth(S32 width) { mRightWidgetsWidth = width; }
|
||||
|
||||
/**
|
||||
* Set all widgets from both side visible/invisible. Only enabled widgets
|
||||
* (see setShowWidget()) can become visible
|
||||
*/
|
||||
virtual void setWidgetsVisible(bool visible);
|
||||
|
||||
/**
|
||||
* Reshape all child widgets - icon, text-box and side widgets
|
||||
*/
|
||||
virtual void reshapeWidgets();
|
||||
|
||||
private:
|
||||
|
||||
/** reshape left side widgets
|
||||
* Deprecated for now. Disabled reshape left for now to reserve space for 'delete'
|
||||
* button in LLPanelClothingListItem according to Neal's comment (https://codereview.productengine.com/secondlife/r/325/)
|
||||
*/
|
||||
void reshapeLeftWidgets();
|
||||
|
||||
/** reshape right side widgets */
|
||||
void reshapeRightWidgets();
|
||||
|
||||
/** reshape remaining widgets */
|
||||
void reshapeMiddleWidgets();
|
||||
|
||||
LLViewerInventoryItem* mItem;
|
||||
|
||||
LLIconCtrl* mIcon;
|
||||
LLTextBox* mTitle;
|
||||
|
||||
LLUIImagePtr mItemIcon;
|
||||
std::string mItemName;
|
||||
std::string mHighlightedText;
|
||||
|
||||
widget_array_t mLeftSideWidgets;
|
||||
widget_array_t mRightSideWidgets;
|
||||
S32 mWidgetSpacing;
|
||||
|
||||
S32 mLeftWidgetsWidth;
|
||||
S32 mRightWidgetsWidth;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LLInventoryItemsList : public LLFlatListView
|
||||
{
|
||||
public:
|
||||
|
|
@ -117,7 +214,7 @@ protected:
|
|||
/**
|
||||
* Add an item to the list
|
||||
*/
|
||||
void addNewItem(LLViewerInventoryItem* item);
|
||||
virtual void addNewItem(LLViewerInventoryItem* item);
|
||||
|
||||
private:
|
||||
uuid_vec_t mIDs; // IDs of items that were added in refreshList().
|
||||
|
|
|
|||
|
|
@ -167,8 +167,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
LLTextureFetchWorker(LLTextureFetch* fetcher, const LLUUID& id, const LLHost& host,
|
||||
F32 priority, S32 discard, S32 size);
|
||||
LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host,
|
||||
F32 priority, S32 discard, S32 size);
|
||||
|
||||
|
|
@ -215,8 +213,15 @@ private:
|
|||
QUEUED = 1,
|
||||
SENT_SIM = 2
|
||||
};
|
||||
enum e_write_to_cache_state //mWriteToCacheState
|
||||
{
|
||||
NOT_WRITE = 0,
|
||||
CAN_WRITE = 1,
|
||||
SHOULD_WRITE = 2
|
||||
};
|
||||
static const char* sStateDescs[];
|
||||
e_state mState;
|
||||
e_write_to_cache_state mWriteToCacheState;
|
||||
LLTextureFetch* mFetcher;
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
LLPointer<LLImageRaw> mRawImage;
|
||||
|
|
@ -377,6 +382,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
|
|||
S32 size) // Desired size
|
||||
: LLWorkerClass(fetcher, "TextureFetch"),
|
||||
mState(INIT),
|
||||
mWriteToCacheState(NOT_WRITE),
|
||||
mFetcher(fetcher),
|
||||
mID(id),
|
||||
mHost(host),
|
||||
|
|
@ -595,7 +601,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
}
|
||||
|
||||
if (mState == INIT)
|
||||
{
|
||||
{
|
||||
mRawImage = NULL ;
|
||||
mRequestedDiscard = -1;
|
||||
mLoadedDiscard = -1;
|
||||
|
|
@ -636,17 +642,18 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
mFileSize = 0;
|
||||
mLoaded = FALSE;
|
||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
|
||||
|
||||
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
||||
|
||||
if (mUrl.compare(0, 7, "file://") == 0)
|
||||
{
|
||||
// read file from local disk
|
||||
std::string filename = mUrl.substr(7, std::string::npos);
|
||||
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
||||
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
|
||||
offset, size, responder);
|
||||
}
|
||||
else if (mUrl.empty())
|
||||
{
|
||||
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
||||
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
|
||||
offset, size, responder);
|
||||
}
|
||||
|
|
@ -659,8 +666,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
}
|
||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||
mState = SEND_HTTP_REQ;
|
||||
delete responder;
|
||||
responder = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -694,6 +699,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
llassert_always(mFormattedImage->getDataSize() > 0);
|
||||
mLoadedDiscard = mDesiredDiscard;
|
||||
mState = DECODE_IMAGE;
|
||||
mWriteToCacheState = NOT_WRITE ;
|
||||
LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
|
||||
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
|
||||
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
|
||||
|
|
@ -735,6 +741,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
if (!http_url.empty())
|
||||
{
|
||||
mUrl = http_url + "/?texture_id=" + mID.asString().c_str();
|
||||
mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -747,12 +754,17 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
{
|
||||
mState = LLTextureFetchWorker::SEND_HTTP_REQ;
|
||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||
if(mWriteToCacheState != NOT_WRITE)
|
||||
{
|
||||
mWriteToCacheState = CAN_WRITE ;
|
||||
}
|
||||
// don't return, fall through to next state
|
||||
}
|
||||
else if (mSentRequest == UNSENT)
|
||||
{
|
||||
// Add this to the network queue and sit here.
|
||||
// LLTextureFetch::update() will send off a request which will change our state
|
||||
mWriteToCacheState = CAN_WRITE ;
|
||||
mRequestedSize = mDesiredSize;
|
||||
mRequestedDiscard = mDesiredDiscard;
|
||||
mSentRequest = QUEUED;
|
||||
|
|
@ -789,6 +801,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
}
|
||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||
mState = DECODE_IMAGE;
|
||||
mWriteToCacheState = SHOULD_WRITE ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -850,7 +863,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
mState = WAIT_HTTP_REQ;
|
||||
|
||||
mFetcher->addToHTTPQueue(mID);
|
||||
mSentRequest = QUEUED;
|
||||
// Will call callbackHttpGet when curl request completes
|
||||
std::vector<std::string> headers;
|
||||
headers.push_back("Accept: image/x-j2c");
|
||||
|
|
@ -933,15 +945,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
}
|
||||
|
||||
llassert_always(mBufferSize == cur_size + mRequestedSize);
|
||||
if (mHaveAllData)
|
||||
if (mHaveAllData && mRequestedDiscard == 0) //the image file is fully loaded.
|
||||
{
|
||||
mFileSize = mBufferSize;
|
||||
}
|
||||
else //the file size is unknown
|
||||
else //the file size is unknown.
|
||||
{
|
||||
mFileSize = S32_MAX ; //flag the file is not fully loaded.
|
||||
mFileSize = mBufferSize + 1 ; //flag the file is not fully loaded.
|
||||
}
|
||||
|
||||
|
||||
U8* buffer = new U8[mBufferSize];
|
||||
if (cur_size > 0)
|
||||
{
|
||||
|
|
@ -956,6 +968,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
mBufferSize = 0;
|
||||
mLoadedDiscard = mRequestedDiscard;
|
||||
mState = DECODE_IMAGE;
|
||||
if(mWriteToCacheState != NOT_WRITE)
|
||||
{
|
||||
mWriteToCacheState = SHOULD_WRITE ;
|
||||
}
|
||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1055,7 +1071,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
|
||||
if (mState == WRITE_TO_CACHE)
|
||||
{
|
||||
if (mInLocalCache || mSentRequest == UNSENT || mFormattedImage.isNull())
|
||||
if (mWriteToCacheState != SHOULD_WRITE || mFormattedImage.isNull())
|
||||
{
|
||||
// If we're in a local cache or we didn't actually receive any new data,
|
||||
// or we failed to load anything, skip
|
||||
|
|
@ -1063,6 +1079,17 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
return false;
|
||||
}
|
||||
S32 datasize = mFormattedImage->getDataSize();
|
||||
if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed.
|
||||
{
|
||||
if(mHaveAllData)
|
||||
{
|
||||
mFileSize = datasize ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFileSize = datasize + 1 ; //flag not fully loaded.
|
||||
}
|
||||
}
|
||||
llassert_always(datasize);
|
||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
|
||||
U32 cache_priority = mWorkPriority;
|
||||
|
|
|
|||
|
|
@ -1914,7 +1914,15 @@ void LLViewerMediaImpl::updateVolume()
|
|||
{
|
||||
if(mMediaSource)
|
||||
{
|
||||
mMediaSource->setVolume(mRequestedVolume * LLViewerMedia::getVolume());
|
||||
F32 attenuation_multiplier = 1.0;
|
||||
|
||||
if (mProximityDistance > 0)
|
||||
{
|
||||
// the attenuation multiplier should never be more than one since that would increase volume
|
||||
attenuation_multiplier = llmin(1.0, gSavedSettings.getF32("MediaRollOffFactor")/mProximityDistance);
|
||||
}
|
||||
|
||||
mMediaSource->setVolume(mRequestedVolume * LLViewerMedia::getVolume() * attenuation_multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2427,6 +2435,8 @@ void LLViewerMediaImpl::update()
|
|||
}
|
||||
else
|
||||
{
|
||||
updateVolume();
|
||||
|
||||
// If we didn't just create the impl, it may need to get cookie updates.
|
||||
if(!sUpdatedCookies.empty())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,6 +60,158 @@ bool LLFindOutfitItems::operator()(LLInventoryCategory* cat,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void LLPanelWearableListItem::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanelInventoryListItemBase::onMouseEnter(x, y, mask);
|
||||
setWidgetsVisible(true);
|
||||
reshapeWidgets();
|
||||
}
|
||||
|
||||
void LLPanelWearableListItem::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLPanelInventoryListItemBase::onMouseLeave(x, y, mask);
|
||||
setWidgetsVisible(false);
|
||||
reshapeWidgets();
|
||||
}
|
||||
|
||||
LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item)
|
||||
: LLPanelInventoryListItemBase(item)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
LLPanelClothingListItem* LLPanelClothingListItem::create(LLViewerInventoryItem* item)
|
||||
{
|
||||
LLPanelClothingListItem* list_item = NULL;
|
||||
if(item)
|
||||
{
|
||||
list_item = new LLPanelClothingListItem(item);
|
||||
list_item->init();
|
||||
}
|
||||
return list_item;
|
||||
}
|
||||
|
||||
LLPanelClothingListItem::LLPanelClothingListItem(LLViewerInventoryItem* item)
|
||||
: LLPanelWearableListItem(item)
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelClothingListItem::~LLPanelClothingListItem()
|
||||
{
|
||||
}
|
||||
|
||||
void LLPanelClothingListItem::init()
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_clothing_list_item.xml");
|
||||
}
|
||||
|
||||
BOOL LLPanelClothingListItem::postBuild()
|
||||
{
|
||||
LLPanelInventoryListItemBase::postBuild();
|
||||
|
||||
addWidgetToLeftSide("btn_delete");
|
||||
addWidgetToRightSide("btn_move_up");
|
||||
addWidgetToRightSide("btn_move_down");
|
||||
addWidgetToRightSide("btn_lock");
|
||||
addWidgetToRightSide("btn_edit");
|
||||
|
||||
LLButton* delete_btn = getChild<LLButton>("btn_delete");
|
||||
// Reserve space for 'delete' button event if it is invisible.
|
||||
setLeftWidgetsWidth(delete_btn->getRect().mRight);
|
||||
|
||||
setWidgetsVisible(false);
|
||||
reshapeWidgets();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelClothingListItem::setShowDeleteButton(bool show)
|
||||
{
|
||||
setShowWidget("btn_delete", show);
|
||||
}
|
||||
|
||||
void LLPanelClothingListItem::setShowMoveUpButton(bool show)
|
||||
{
|
||||
setShowWidget("btn_move_up", show);
|
||||
}
|
||||
|
||||
void LLPanelClothingListItem::setShowMoveDownButton(bool show)
|
||||
{
|
||||
setShowWidget("btn_move_down", show);
|
||||
}
|
||||
|
||||
void LLPanelClothingListItem::setShowLockButton(bool show)
|
||||
{
|
||||
setShowWidget("btn_lock", show);
|
||||
}
|
||||
|
||||
void LLPanelClothingListItem::setShowEditButton(bool show)
|
||||
{
|
||||
setShowWidget("btn_edit", show);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
LLPanelBodyPartsListItem* LLPanelBodyPartsListItem::create(LLViewerInventoryItem* item)
|
||||
{
|
||||
LLPanelBodyPartsListItem* list_item = NULL;
|
||||
if(item)
|
||||
{
|
||||
list_item = new LLPanelBodyPartsListItem(item);
|
||||
list_item->init();
|
||||
}
|
||||
return list_item;
|
||||
}
|
||||
|
||||
LLPanelBodyPartsListItem::LLPanelBodyPartsListItem(LLViewerInventoryItem* item)
|
||||
: LLPanelWearableListItem(item)
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelBodyPartsListItem::~LLPanelBodyPartsListItem()
|
||||
{
|
||||
}
|
||||
|
||||
void LLPanelBodyPartsListItem::init()
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_body_parts_list_item.xml");
|
||||
}
|
||||
|
||||
BOOL LLPanelBodyPartsListItem::postBuild()
|
||||
{
|
||||
LLPanelInventoryListItemBase::postBuild();
|
||||
|
||||
addWidgetToRightSide("btn_lock");
|
||||
addWidgetToRightSide("btn_edit");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLPanelBodyPartsListItem::setShowLockButton(bool show)
|
||||
{
|
||||
setShowWidget("btn_lock", show);
|
||||
}
|
||||
|
||||
void LLPanelBodyPartsListItem::setShowEditButton(bool show)
|
||||
{
|
||||
setShowWidget("btn_edit", show);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
|
||||
|
||||
LLWearableItemsList::Params::Params()
|
||||
|
|
@ -89,3 +241,5 @@ void LLWearableItemsList::updateList(const LLUUID& category_id)
|
|||
|
||||
refreshList(item_array);
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
|||
|
|
@ -36,6 +36,89 @@
|
|||
|
||||
// newview
|
||||
#include "llinventoryitemslist.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llwearabledictionary.h"
|
||||
|
||||
/**
|
||||
* @class LLPanelWearableListItem
|
||||
*
|
||||
* Extends LLPanelInventoryListItemBase:
|
||||
* - makes side widgets show on mouse_enter and hide on
|
||||
* mouse_leave events.
|
||||
* - provides callback for button clicks
|
||||
*/
|
||||
class LLPanelWearableListItem : public LLPanelInventoryListItemBase
|
||||
{
|
||||
LOG_CLASS(LLPanelWearableListItem);
|
||||
public:
|
||||
|
||||
/**
|
||||
* Shows buttons when mouse is over
|
||||
*/
|
||||
/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
|
||||
/**
|
||||
* Hides buttons when mouse is out
|
||||
*/
|
||||
/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
||||
protected:
|
||||
|
||||
LLPanelWearableListItem(LLViewerInventoryItem* item);
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLPanelClothingListItem
|
||||
*
|
||||
* Provides buttons for editing, moving, deleting a wearable.
|
||||
*/
|
||||
class LLPanelClothingListItem : public LLPanelWearableListItem
|
||||
{
|
||||
LOG_CLASS(LLPanelClothingListItem);
|
||||
public:
|
||||
|
||||
static LLPanelClothingListItem* create(LLViewerInventoryItem* item);
|
||||
|
||||
virtual ~LLPanelClothingListItem();
|
||||
|
||||
/*virtual*/ void init();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
/**
|
||||
* Make button visible during mouse over event.
|
||||
*/
|
||||
inline void setShowDeleteButton(bool show);
|
||||
inline void setShowMoveUpButton(bool show);
|
||||
inline void setShowMoveDownButton(bool show);
|
||||
inline void setShowLockButton(bool show);
|
||||
inline void setShowEditButton(bool show);
|
||||
|
||||
protected:
|
||||
|
||||
LLPanelClothingListItem(LLViewerInventoryItem* item);
|
||||
};
|
||||
|
||||
class LLPanelBodyPartsListItem : public LLPanelWearableListItem
|
||||
{
|
||||
LOG_CLASS(LLPanelBodyPartsListItem);
|
||||
public:
|
||||
|
||||
static LLPanelBodyPartsListItem* create(LLViewerInventoryItem* item);
|
||||
|
||||
virtual ~LLPanelBodyPartsListItem();
|
||||
|
||||
/*virtual*/ void init();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
/**
|
||||
* Make button visible during mouse over event.
|
||||
*/
|
||||
inline void setShowLockButton(bool show);
|
||||
inline void setShowEditButton(bool show);
|
||||
|
||||
protected:
|
||||
LLPanelBodyPartsListItem(LLViewerInventoryItem* item);
|
||||
};
|
||||
|
||||
/**
|
||||
* @class LLWearableItemsList
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
follows="top|right|left"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="wearable_item"
|
||||
top="0"
|
||||
width="380">
|
||||
<icon
|
||||
follows="top|right|left"
|
||||
height="20"
|
||||
image_name="ListItem_Over"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="hovered_icon"
|
||||
top="0"
|
||||
visible="false"
|
||||
width="380" />
|
||||
<icon
|
||||
height="20"
|
||||
follows="top|right|left"
|
||||
image_name="ListItem_Select"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="selected_icon"
|
||||
top="0"
|
||||
visible="false"
|
||||
width="380" />
|
||||
<icon
|
||||
height="16"
|
||||
follows="top|left"
|
||||
image_name="Inv_Object"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="item_icon"
|
||||
top="2"
|
||||
width="16" />
|
||||
<text
|
||||
follows="left|right"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
allow_html="false"
|
||||
use_ellipses="true"
|
||||
name="item_name"
|
||||
text_color="white"
|
||||
top="4"
|
||||
value="..."
|
||||
width="359" />
|
||||
<button
|
||||
name="btn_lock"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
image_unselected="Lock2"
|
||||
image_selected="Lock2"
|
||||
top="0"
|
||||
left_pad="3"
|
||||
height="20"
|
||||
width="20"
|
||||
tab_stop="false" />
|
||||
<button
|
||||
name="btn_edit"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
image_unselected="Icon_Gear_Background"
|
||||
image_selected="Icon_Gear_Background"
|
||||
top="0"
|
||||
left_pad="3"
|
||||
height="20"
|
||||
width="20"
|
||||
tab_stop="false" />
|
||||
</panel>
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<panel
|
||||
follows="top|right|left"
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="wearable_item"
|
||||
top="0"
|
||||
width="380">
|
||||
<icon
|
||||
follows="top|right|left"
|
||||
height="20"
|
||||
image_name="ListItem_Over"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="hovered_icon"
|
||||
top="0"
|
||||
visible="false"
|
||||
width="380" />
|
||||
<icon
|
||||
height="20"
|
||||
follows="top|right|left"
|
||||
image_name="ListItem_Select"
|
||||
layout="topleft"
|
||||
left="0"
|
||||
name="selected_icon"
|
||||
top="0"
|
||||
visible="false"
|
||||
width="380" />
|
||||
<button
|
||||
name="btn_delete"
|
||||
layout="topleft"
|
||||
follows="top|left"
|
||||
image_unselected="Toast_CloseBtn"
|
||||
image_selected="Toast_CloseBtn"
|
||||
top="0"
|
||||
left="0"
|
||||
height="20"
|
||||
width="20"
|
||||
tab_stop="false" />
|
||||
<icon
|
||||
height="16"
|
||||
follows="top|left"
|
||||
image_name="Inv_Object"
|
||||
layout="topleft"
|
||||
left_pad="3"
|
||||
name="item_icon"
|
||||
top="2"
|
||||
width="16" />
|
||||
<text
|
||||
follows="left|right"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left_pad="5"
|
||||
allow_html="false"
|
||||
use_ellipses="true"
|
||||
name="item_name"
|
||||
text_color="white"
|
||||
top="4"
|
||||
value="..."
|
||||
width="359" />
|
||||
<button
|
||||
name="btn_move_up"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
image_unselected="Movement_Up_Off"
|
||||
image_selected="Movement_Up_Off"
|
||||
top="0"
|
||||
left="0"
|
||||
height="20"
|
||||
width="20"
|
||||
tab_stop="false" />
|
||||
<button
|
||||
name="btn_move_down"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
image_unselected="Movement_Down_Off"
|
||||
image_selected="Movement_Down_Off"
|
||||
top="0"
|
||||
left_pad="3"
|
||||
height="20"
|
||||
width="20"
|
||||
tab_stop="false" />
|
||||
<button
|
||||
name="btn_lock"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
image_unselected="Lock2"
|
||||
image_selected="Lock2"
|
||||
top="0"
|
||||
left_pad="3"
|
||||
height="20"
|
||||
width="20"
|
||||
tab_stop="false" />
|
||||
<button
|
||||
name="btn_edit"
|
||||
layout="topleft"
|
||||
follows="top|right"
|
||||
image_unselected="Icon_Gear_Background"
|
||||
image_selected="Icon_Gear_Background"
|
||||
top="0"
|
||||
left_pad="3"
|
||||
height="20"
|
||||
width="20"
|
||||
tab_stop="false" />
|
||||
</panel>
|
||||
|
|
@ -15,6 +15,6 @@
|
|||
<menu_item_call label="Disattiva audio di questo participante" name="ModerateVoiceMuteSelected"/>
|
||||
<menu_item_call label="Disattiva audio di tutti gli altri" name="ModerateVoiceMuteOthers"/>
|
||||
<menu_item_call label="Riattiva audio di questo participante" name="ModerateVoiceUnMuteSelected"/>
|
||||
<menu_item_call label="Disattiva audio di tutti gli altri" name="ModerateVoiceUnMuteOthers"/>
|
||||
<menu_item_call label="Riattiva audio di tutti gli altri" name="ModerateVoiceUnMuteOthers"/>
|
||||
</context_menu>
|
||||
</context_menu>
|
||||
|
|
|
|||
|
|
@ -898,7 +898,7 @@ Unisci il terreno?
|
|||
In genere si tratta di un problema temporaneo. Attendi alcuni minuti per modificare e salvare nuovamente gli elementi indossabili.
|
||||
</notification>
|
||||
<notification name="YouHaveBeenLoggedOut">
|
||||
Accidenti. Sei stato scollegato da [SECOND_LIFE]
|
||||
Sei stato scollegato da [SECOND_LIFE].
|
||||
[MESSAGE]
|
||||
<usetemplate name="okcancelbuttons" notext="Esci" yestext="Vedi IM & Chat"/>
|
||||
</notification>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<panel label="Modifica scelta" name="panel_edit_pick">
|
||||
<panel label="Modifica preferito" name="panel_edit_pick">
|
||||
<panel.string name="location_notice">
|
||||
(si aggiornerà dopo il salvataggio)
|
||||
</panel.string>
|
||||
<text name="title">
|
||||
Modifica scelta
|
||||
Modifica preferito
|
||||
</text>
|
||||
<scroll_container name="profile_scroll">
|
||||
<panel name="scroll_content_panel">
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@
|
|||
</text>
|
||||
<check_box label="Costruire/Modificare" name="edit_camera_movement" tool_tip="Utilizza il posizionamento automatico della fotocamera entrando o uscendo dalla modalità modifica"/>
|
||||
<check_box label="Aspetto fisico" name="appearance_camera_movement" tool_tip="Utilizza il posizionamento automatico della camera in modalità modifica"/>
|
||||
<check_box label="Mostra in modalità Mouselook" name="first_person_avatar_visible"/>
|
||||
<check_box label="Visualizzami in modalità soggettiva" name="first_person_avatar_visible"/>
|
||||
<check_box label="Le frecce di direzione mi fanno sempre spostare" name="arrow_keys_move_avatar_check"/>
|
||||
<check_box label="Doppio click e tieni premuto per correre" name="tap_tap_hold_to_run"/>
|
||||
<check_box label="Consente il movimento delle labbra dell'avatar quando parla" name="enable_lip_sync"/>
|
||||
<check_box label="Movimento delle labbra dell'avatar quando parla" name="enable_lip_sync"/>
|
||||
<check_box label="Chat a bolla" name="bubble_text_chat"/>
|
||||
<slider label="Opacità" name="bubble_chat_opacity"/>
|
||||
<color_swatch name="background" tool_tip="Scegli il colore delle vignette della chat"/>
|
||||
|
|
|
|||
|
|
@ -886,13 +886,13 @@
|
|||
Alto
|
||||
</string>
|
||||
<string name="LeaveMouselook">
|
||||
Premi ESC per tornare in visulizzazione normale
|
||||
Premi ESC per tornare in visualizzazione normale
|
||||
</string>
|
||||
<string name="InventoryNoMatchingItems">
|
||||
Nessun oggetto corrispondente trovato in inventario. Prova [secondlife:///app/search/groups "Cerca"].
|
||||
</string>
|
||||
<string name="FavoritesNoMatchingItems">
|
||||
Trascina qui un punto di riferimento per aggiungerlo ai tuoi preferiti.
|
||||
Trascina qui un punto di riferimento per aggiungerlo ai Preferiti.
|
||||
</string>
|
||||
<string name="InventoryNoTexture">
|
||||
Non hai una copia di questa texture nel tuo inventario
|
||||
|
|
@ -1566,7 +1566,7 @@
|
|||
(si aggiornerà dopo la pubblicazione)
|
||||
</string>
|
||||
<string name="NoPicksClassifiedsText">
|
||||
Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante più qui sotto per creare un luogo preferito o un'inserzione.
|
||||
Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un'inserzione.
|
||||
</string>
|
||||
<string name="NoAvatarPicksClassifiedsText">
|
||||
L'utente non ha luoghi preferiti né inserzioni
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ Se si continua a visualizzare questo messaggio, consulta la pagina [SUPPORT_SITE
|
|||
Elaborazione della destinazione in corso...
|
||||
</message>
|
||||
<message name="contacting">
|
||||
Contattando la nuova regione.
|
||||
Contatto in corso con la nuova regione.
|
||||
</message>
|
||||
<message name="arriving">
|
||||
In arrivo a destinazione...
|
||||
|
|
|
|||
Loading…
Reference in New Issue