summaryrefslogtreecommitdiff
path: root/indra/llui/llcombobox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llcombobox.cpp')
-rw-r--r--indra/llui/llcombobox.cpp103
1 files changed, 67 insertions, 36 deletions
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 36e309d639..3a8efadaa4 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -102,14 +102,15 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
mMaxChars(p.max_chars),
mPrearrangeCallback(p.prearrange_callback()),
mTextEntryCallback(p.text_entry_callback()),
- mSelectionCallback(p.selection_callback()),
mListPosition(p.list_position),
- mLastSelectedIndex(-1)
+ mLastSelectedIndex(-1),
+ mLabel(p.label)
{
// Text label button
LLButton::Params button_params = (mAllowTextEntry ? p.combo_button : p.drop_down_button);
- button_params.mouse_down_callback.function(boost::bind(&LLComboBox::onButtonDown, this));
+ button_params.mouse_down_callback.function(
+ boost::bind(&LLComboBox::onButtonMouseDown, this));
button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT);
button_params.rect(p.rect);
@@ -140,6 +141,10 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
mList = LLUICtrlFactory::create<LLScrollListCtrl>(params);
addChild(mList);
+ // Mouse-down on button will transfer mouse focus to the list
+ // Grab the mouse-up event and make sure the button state is correct
+ mList->setMouseUpCallback(boost::bind(&LLComboBox::onListMouseUp, this));
+
for (LLInitParam::ParamIterator<ItemParams>::const_iterator it = p.items().begin();
it != p.items().end();
++it)
@@ -155,7 +160,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)
createLineEditor(p);
- setTopLostCallback(boost::bind(&LLComboBox::hideList, this));
+ mTopLostSignalConnection = setTopLostCallback(boost::bind(&LLComboBox::hideList, this));
}
void LLComboBox::initFromParams(const LLComboBox::Params& p)
@@ -182,6 +187,9 @@ BOOL LLComboBox::postBuild()
LLComboBox::~LLComboBox()
{
// children automatically deleted, including mMenu, mButton
+
+ // explicitly disconect this signal, since base class destructor might fire top lost
+ mTopLostSignalConnection.disconnect();
}
@@ -315,15 +323,19 @@ void LLComboBox::setValue(const LLSD& value)
LLScrollListItem* item = mList->getFirstSelected();
if (item)
{
- setLabel( mList->getSelectedItemLabel() );
+ setLabel(getSelectedItemLabel());
}
mLastSelectedIndex = mList->getFirstSelectedIndex();
}
+ else
+ {
+ mLastSelectedIndex = -1;
+ }
}
const std::string LLComboBox::getSimple() const
{
- const std::string res = mList->getSelectedItemLabel();
+ const std::string res = getSelectedItemLabel();
if (res.empty() && mAllowTextEntry)
{
return mTextEntry->getText();
@@ -402,7 +414,7 @@ BOOL LLComboBox::remove(S32 index)
if (index < mList->getItemCount())
{
mList->deleteSingleItem(index);
- setLabel(mList->getSelectedItemLabel());
+ setLabel(getSelectedItemLabel());
return TRUE;
}
return FALSE;
@@ -443,7 +455,7 @@ BOOL LLComboBox::setCurrentByIndex( S32 index )
BOOL found = mList->selectNthItem( index );
if (found)
{
- setLabel(mList->getSelectedItemLabel());
+ setLabel(getSelectedItemLabel());
mLastSelectedIndex = index;
}
return found;
@@ -486,6 +498,7 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
params.handle_edit_keys_directly(true);
params.commit_on_focus_lost(false);
params.follows.flags(FOLLOWS_ALL);
+ params.label(mLabel);
mTextEntry = LLUICtrlFactory::create<LLLineEditor> (params);
mTextEntry->setText(cur_label);
mTextEntry->setIgnoreTab(TRUE);
@@ -501,7 +514,8 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p)
mButton->setRect(rect);
mButton->setTabStop(TRUE);
mButton->setHAlign(LLFontGL::LEFT);
-
+ mButton->setLabel(mLabel.getString());
+
if (mTextEntry)
{
mTextEntry->setVisible(FALSE);
@@ -605,16 +619,14 @@ void LLComboBox::showList()
mList->setFocus(TRUE);
- // register ourselves as a "top" control
- // effectively putting us into a special draw layer
- // and not affecting the bounding rectangle calculation
- gFocusMgr.setTopCtrl(this);
-
// Show the list and push the button down
mButton->setToggleState(TRUE);
mList->setVisible(TRUE);
+ LLUI::addPopup(this);
+
setUseBoundingRect(TRUE);
+// updateBoundingRect();
}
void LLComboBox::hideList()
@@ -629,7 +641,7 @@ void LLComboBox::hideList()
if(mLastSelectedIndex >= 0)
mList->selectNthItem(mLastSelectedIndex);
}
- else
+ else if(mLastSelectedIndex >= 0)
mList->selectNthItem(mLastSelectedIndex);
mButton->setToggleState(FALSE);
@@ -637,14 +649,12 @@ void LLComboBox::hideList()
mList->mouseOverHighlightNthItem(-1);
setUseBoundingRect(FALSE);
- if( gFocusMgr.getTopCtrl() == this )
- {
- gFocusMgr.setTopCtrl(NULL);
- }
+ LLUI::removePopup(this);
+// updateBoundingRect();
}
}
-void LLComboBox::onButtonDown()
+void LLComboBox::onButtonMouseDown()
{
if (!mList->getVisible())
{
@@ -670,6 +680,10 @@ void LLComboBox::onButtonDown()
if (mButton->hasMouseCapture())
{
gFocusMgr.setMouseCapture(mList);
+
+ // But keep the "pressed" look, which buttons normally lose when they
+ // lose focus
+ mButton->setForcePressedState(true);
}
}
else
@@ -679,6 +693,12 @@ void LLComboBox::onButtonDown()
}
+void LLComboBox::onListMouseUp()
+{
+ // In some cases this is the termination of a mouse click that started on
+ // the button, so clear its pressed state
+ mButton->setForcePressedState(false);
+}
//------------------------------------------------------------------
// static functions
@@ -686,13 +706,10 @@ void LLComboBox::onButtonDown()
void LLComboBox::onItemSelected(const LLSD& data)
{
- const std::string name = mList->getSelectedItemLabel();
-
- S32 cur_id = getCurrentIndex();
- mLastSelectedIndex = cur_id;
- if (cur_id != -1)
+ mLastSelectedIndex = getCurrentIndex();
+ if (mLastSelectedIndex != -1)
{
- setLabel(name);
+ setLabel(getSelectedItemLabel());
if (mAllowTextEntry)
{
@@ -700,18 +717,11 @@ void LLComboBox::onItemSelected(const LLSD& data)
mTextEntry->selectAll();
}
}
-
// hiding the list reasserts the old value stored in the text editor/dropdown button
hideList();
// commit does the reverse, asserting the value in the list
onCommit();
-
- // call the callback if it exists
- if(mSelectionCallback)
- {
- mSelectionCallback(this, data);
- }
}
BOOL LLComboBox::handleToolTip(S32 x, S32 y, MASK mask)
@@ -901,7 +911,7 @@ void LLComboBox::updateSelection()
}
else if (mList->selectItemByPrefix(left_wstring, FALSE))
{
- LLWString selected_item = utf8str_to_wstring(mList->getSelectedItemLabel());
+ LLWString selected_item = utf8str_to_wstring(getSelectedItemLabel());
LLWString wtext = left_wstring + selected_item.substr(left_wstring.size(), selected_item.size());
mTextEntry->setText(wstring_to_utf8str(wtext));
mTextEntry->setSelection(left_wstring.size(), mTextEntry->getWText().size());
@@ -1003,7 +1013,7 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id)
if (found)
{
- setLabel(mList->getSelectedItemLabel());
+ setLabel(getSelectedItemLabel());
mLastSelectedIndex = mList->getFirstSelectedIndex();
}
@@ -1019,7 +1029,7 @@ BOOL LLComboBox::setSelectedByValue(const LLSD& value, BOOL selected)
BOOL found = mList->setSelectedByValue(value, selected);
if (found)
{
- setLabel(mList->getSelectedItemLabel());
+ setLabel(getSelectedItemLabel());
}
return found;
}
@@ -1058,3 +1068,24 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last )
{
return mList->selectItemRange(first, last);
}
+
+
+static LLDefaultChildRegistry::Register<LLIconsComboBox> register_icons_combo_box("icons_combo_box");
+
+LLIconsComboBox::Params::Params()
+: icon_column("icon_column", ICON_COLUMN),
+ label_column("label_column", LABEL_COLUMN)
+{}
+
+LLIconsComboBox::LLIconsComboBox(const LLIconsComboBox::Params& p)
+: LLComboBox(p),
+ mIconColumnIndex(p.icon_column),
+ mLabelColumnIndex(p.label_column)
+{}
+
+const std::string LLIconsComboBox::getSelectedItemLabel(S32 column) const
+{
+ mButton->setImageOverlay(LLComboBox::getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign());
+
+ return LLComboBox::getSelectedItemLabel(mLabelColumnIndex);
+}