summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llcombobox.cpp52
-rw-r--r--indra/llui/llcombobox.h4
-rw-r--r--indra/llui/llflatlistview.cpp6
-rw-r--r--indra/llui/llfloater.cpp17
-rw-r--r--indra/llui/llfocusmgr.cpp51
-rw-r--r--indra/llui/llfocusmgr.h10
-rw-r--r--indra/llui/llhandle.h7
-rw-r--r--indra/llui/llmodaldialog.cpp6
-rw-r--r--indra/llui/llui.cpp38
-rw-r--r--indra/llui/llui.h12
-rw-r--r--indra/llui/llview.cpp13
-rw-r--r--indra/llui/llview.h4
12 files changed, 120 insertions, 100 deletions
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 98c9217306..c1d512e148 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -160,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)
@@ -187,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();
}
@@ -320,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();
@@ -407,7 +414,7 @@ BOOL LLComboBox::remove(S32 index)
if (index < mList->getItemCount())
{
mList->deleteSingleItem(index);
- setLabel(mList->getSelectedItemLabel());
+ setLabel(getSelectedItemLabel());
return TRUE;
}
return FALSE;
@@ -448,7 +455,7 @@ BOOL LLComboBox::setCurrentByIndex( S32 index )
BOOL found = mList->selectNthItem( index );
if (found)
{
- setLabel(mList->getSelectedItemLabel());
+ setLabel(getSelectedItemLabel());
mLastSelectedIndex = index;
}
return found;
@@ -612,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()
@@ -644,10 +649,8 @@ void LLComboBox::hideList()
mList->mouseOverHighlightNthItem(-1);
setUseBoundingRect(FALSE);
- if( gFocusMgr.getTopCtrl() == this )
- {
- gFocusMgr.setTopCtrl(NULL);
- }
+ LLUI::removePopup(this);
+// updateBoundingRect();
}
}
@@ -905,7 +908,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());
@@ -1007,7 +1010,7 @@ BOOL LLComboBox::setCurrentByID(const LLUUID& id)
if (found)
{
- setLabel(mList->getSelectedItemLabel());
+ setLabel(getSelectedItemLabel());
mLastSelectedIndex = mList->getFirstSelectedIndex();
}
@@ -1023,7 +1026,7 @@ BOOL LLComboBox::setSelectedByValue(const LLSD& value, BOOL selected)
BOOL found = mList->setSelectedByValue(value, selected);
if (found)
{
- setLabel(mList->getSelectedItemLabel());
+ setLabel(getSelectedItemLabel());
}
return found;
}
@@ -1085,10 +1088,19 @@ void LLIconsComboBox::setValue(const LLSD& value)
LLScrollListItem* item = mList->getFirstSelected();
if (item)
{
- mButton->setImageOverlay(mList->getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign());
-
- setLabel(mList->getSelectedItemLabel(mLabelColumnIndex));
+ setLabel(getSelectedItemLabel());
}
mLastSelectedIndex = mList->getFirstSelectedIndex();
}
+ else
+ {
+ mLastSelectedIndex = -1;
+ }
+}
+
+const std::string LLIconsComboBox::getSelectedItemLabel(S32 column) const
+{
+ mButton->setImageOverlay(LLComboBox::getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign());
+
+ return LLComboBox::getSelectedItemLabel(mLabelColumnIndex);
}
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 3cc2a8f5d1..965061ead2 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -150,7 +150,7 @@ public:
// Get name of current item. Returns an empty string if not found.
const std::string getSimple() const;
// Get contents of column x of selected row
- const std::string getSelectedItemLabel(S32 column = 0) const;
+ virtual const std::string getSelectedItemLabel(S32 column = 0) const;
// Sets the label, which doesn't have to exist in the label.
// This is probably a UI abuse.
@@ -231,6 +231,7 @@ private:
commit_callback_t mPrearrangeCallback;
commit_callback_t mTextEntryCallback;
commit_callback_t mSelectionCallback;
+ boost::signals2::connection mTopLostSignalConnection;
};
// A combo box with icons for the list of items.
@@ -247,6 +248,7 @@ public:
};
/*virtual*/ void setValue(const LLSD& value);
+ /*virtual*/ const std::string getSelectedItemLabel(S32 column = 0) const;
private:
enum EColumnIndex
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 2481249f91..2e5aeec41d 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -492,6 +492,12 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
{
if (!item_pair) return;
+ if (!item_pair->first)
+ {
+ llwarning("Attempt to selet an item pair containing null panel item", 0);
+ return;
+ }
+
setFocus(TRUE);
bool select_item = !isSelected(item_pair);
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 1ba8b6964d..d5b76d12cc 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -527,10 +527,7 @@ void LLFloater::setVisible( BOOL visible )
if( !visible )
{
- if( gFocusMgr.childIsTopCtrl( this ) )
- {
- gFocusMgr.setTopCtrl(NULL);
- }
+ LLUI::removePopup(this);
if( gFocusMgr.childHasMouseCapture( this ) )
{
@@ -704,10 +701,7 @@ void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLFloater::releaseFocus()
{
- if( gFocusMgr.childIsTopCtrl( this ) )
- {
- gFocusMgr.setTopCtrl(NULL);
- }
+ LLUI::removePopup(this);
setFocus(FALSE);
@@ -1360,7 +1354,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
// virtual
void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
{
- gFocusMgr.setTopCtrl(NULL);
+ LLUI::clearPopups();
setVisible(TRUE);
setFrontmost(take_focus);
}
@@ -2508,10 +2502,7 @@ void LLFloaterView::syncFloaterTabOrder()
if (modal_dialog)
{
// If we have a visible modal dialog, make sure that it has focus
- if( gFocusMgr.getTopCtrl() != modal_dialog )
- {
- gFocusMgr.setTopCtrl( modal_dialog );
- }
+ LLUI::addPopup(modal_dialog);
if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) )
{
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 35fbc7b0a8..b3af258456 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -38,8 +38,6 @@
const F32 FOCUS_FADE_TIME = 0.3f;
-// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp.
-
LLFocusableElement::LLFocusableElement()
: mFocusLostCallback(NULL),
mFocusReceivedCallback(NULL),
@@ -124,8 +122,7 @@ boost::signals2::connection LLFocusableElement::setTopLostCallback(const focus_s
LLFocusMgr gFocusMgr;
LLFocusMgr::LLFocusMgr()
- :
- mLockedView( NULL ),
+: mLockedView( NULL ),
mMouseCaptor( NULL ),
mKeyboardFocus( NULL ),
mLastKeyboardFocus( NULL ),
@@ -133,16 +130,11 @@ LLFocusMgr::LLFocusMgr()
mKeystrokesOnly(FALSE),
mTopCtrl( NULL ),
mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true
- #ifdef _DEBUG
- , mMouseCaptorName("none")
- , mKeyboardFocusName("none")
- , mTopCtrlName("none")
- #endif
{
}
-void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
+void LLFocusMgr::releaseFocusIfNeeded( LLView* view )
{
if( childHasMouseCapture( view ) )
{
@@ -162,10 +154,7 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
}
}
- if( childIsTopCtrl( view ) )
- {
- setTopCtrl( NULL );
- }
+ LLUI::removePopup(view);
}
@@ -248,11 +237,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
return;
}
- #ifdef _DEBUG
- LLUICtrl* focus_ctrl = dynamic_cast<LLUICtrl*>(new_focus);
- mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none");
- #endif
-
// If we've got a default keyboard focus, and the caller is
// releasing keyboard focus, move to the default.
if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL)
@@ -334,20 +318,12 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f
if( mKeyboardFocus == focus )
{
mKeyboardFocus = NULL;
- #ifdef _DEBUG
- mKeyboardFocusName = std::string("none");
- #endif
}
}
void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
{
- //if (mFocusLocked)
- //{
- // return;
- //}
-
if( new_captor != mMouseCaptor )
{
LLMouseHandler* old_captor = mMouseCaptor;
@@ -370,24 +346,14 @@ void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
old_captor->onMouseCaptureLost();
}
- #ifdef _DEBUG
- mMouseCaptorName = new_captor ? new_captor->getName() : std::string("none");
- #endif
}
}
void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor )
{
- //if (mFocusLocked)
- //{
- // return;
- //}
if( mMouseCaptor == captor )
{
mMouseCaptor = NULL;
- #ifdef _DEBUG
- mMouseCaptorName = std::string("none");
- #endif
}
}
@@ -416,10 +382,6 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top )
{
mTopCtrl = new_top;
- #ifdef _DEBUG
- mTopCtrlName = new_top ? new_top->getName() : std::string("none");
- #endif
-
if (old_top)
{
old_top->onTopLost();
@@ -432,9 +394,6 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view )
if( mTopCtrl == top_view )
{
mTopCtrl = NULL;
- #ifdef _DEBUG
- mTopCtrlName = std::string("none");
- #endif
}
}
@@ -478,9 +437,9 @@ void LLFocusMgr::setAppHasFocus(BOOL focus)
}
// release focus from "top ctrl"s, which generally hides them
- if (!focus && mTopCtrl)
+ if (!focus)
{
- setTopCtrl(NULL);
+ LLUI::clearPopups();
}
mAppHasFocus = focus;
}
diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h
index 83ecd1d301..86d3ccf111 100644
--- a/indra/llui/llfocusmgr.h
+++ b/indra/llui/llfocusmgr.h
@@ -65,10 +65,10 @@ public:
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
+ virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
protected:
virtual void onFocusReceived();
virtual void onFocusLost();
- virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
focus_signal_t* mFocusLostCallback;
focus_signal_t* mFocusReceivedCallback;
focus_signal_t* mFocusChangedCallback;
@@ -119,7 +119,7 @@ public:
BOOL childIsTopCtrl( const LLView* parent ) const;
// All Three
- void releaseFocusIfNeeded( const LLView* top_view );
+ void releaseFocusIfNeeded( LLView* top_view );
void lockFocus();
void unlockFocus();
BOOL focusLocked() const { return mLockedView != NULL; }
@@ -149,12 +149,6 @@ private:
typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
focus_history_map_t mFocusHistory;
-
- #ifdef _DEBUG
- std::string mMouseCaptorName;
- std::string mKeyboardFocusName;
- std::string mTopCtrlName;
- #endif
};
extern LLFocusMgr gFocusMgr;
diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
index 899f6b9326..8ade327044 100644
--- a/indra/llui/llhandle.h
+++ b/indra/llui/llhandle.h
@@ -67,6 +67,13 @@ public:
return *this;
}
+ template<typename Subclass>
+ LLHandle<T>& operator =(const LLHandle<Subclass>& other)
+ {
+ mTombStone = other.mTombStone;
+ return *this;
+ }
+
bool isDead() const
{
return mTombStone->getTarget() == NULL;
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 387af05935..6cff68c20b 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -111,7 +111,7 @@ void LLModalDialog::onOpen(const LLSD& key)
// This is a modal dialog. It sucks up all mouse and keyboard operations.
gFocusMgr.setMouseCapture( this );
- gFocusMgr.setTopCtrl( this );
+ LLUI::addPopup(this);
setFocus(TRUE);
sModalStack.push_front( this );
@@ -153,7 +153,7 @@ void LLModalDialog::setVisible( BOOL visible )
gFocusMgr.setMouseCapture( this );
// The dialog view is a root view
- gFocusMgr.setTopCtrl( this );
+ LLUI::addPopup(this);
setFocus( TRUE );
}
else
@@ -291,7 +291,7 @@ void LLModalDialog::onAppFocusGained()
// This is a modal dialog. It sucks up all mouse and keyboard operations.
gFocusMgr.setMouseCapture( instance );
instance->setFocus(TRUE);
- gFocusMgr.setTopCtrl( instance );
+ LLUI::addPopup(instance);
instance->centerOnScreen();
}
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index b348ec2d29..5121ef5351 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -86,6 +86,9 @@ std::list<std::string> gUntranslated;
/*static*/ LLHelp* LLUI::sHelpImpl = NULL;
/*static*/ std::vector<std::string> LLUI::sXUIPaths;
/*static*/ LLFrameTimer LLUI::sMouseIdleTimer;
+/*static*/ LLUI::add_popup_t LLUI::sAddPopupFunc;
+/*static*/ LLUI::remove_popup_t LLUI::sRemovePopupFunc;
+/*static*/ LLUI::clear_popups_t LLUI::sClearPopupsFunc;
// register filtereditor here
static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor");
@@ -1607,6 +1610,13 @@ void LLUI::cleanupClass()
sImageProvider->cleanUp();
}
+void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups)
+{
+ sAddPopupFunc = add_popup;
+ sRemovePopupFunc = remove_popup;
+ sClearPopupsFunc = clear_popups;
+}
+
//static
void LLUI::dirtyRect(LLRect rect)
{
@@ -1877,6 +1887,34 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
return *sSettingGroups["config"]; // default group
}
+//static
+void LLUI::addPopup(LLView* viewp)
+{
+ if (sAddPopupFunc)
+ {
+ sAddPopupFunc(viewp);
+ }
+}
+
+//static
+void LLUI::removePopup(LLView* viewp)
+{
+ if (sRemovePopupFunc)
+ {
+ sRemovePopupFunc(viewp);
+ }
+}
+
+//static
+void LLUI::clearPopups()
+{
+ if (sClearPopupsFunc)
+ {
+ sClearPopupsFunc();
+ }
+}
+
+
//static
// spawn_x and spawn_y are top left corner of view in screen GL coordinates
void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index af8d4ea03b..30f3623ded 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -160,12 +160,17 @@ public:
// Methods
//
typedef std::map<std::string, LLControlGroup*> settings_map_t;
+ typedef boost::function<void(LLView*)> add_popup_t;
+ typedef boost::function<void(LLView*)> remove_popup_t;
+ typedef boost::function<void(void)> clear_popups_t;
+
static void initClass(const settings_map_t& settings,
LLImageProviderInterface* image_provider,
LLUIAudioCallback audio_callback = NULL,
const LLVector2 *scale_factor = NULL,
const std::string& language = LLStringUtil::null);
static void cleanupClass();
+ static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
static void pushMatrix();
static void popMatrix();
@@ -208,6 +213,10 @@ public:
static void resetMouseIdleTimer() { sMouseIdleTimer.reset(); }
static LLWindow* getWindow() { return sWindow; }
+ static void addPopup(LLView*);
+ static void removePopup(LLView*);
+ static void clearPopups();
+
// Ensures view does not overlap mouse cursor, but is inside
// the view's parent rectangle. Used for tooltips, inspectors.
// Optionally override the view's default X/Y, which are relative to the
@@ -227,6 +236,9 @@ private:
static LLImageProviderInterface* sImageProvider;
static std::vector<std::string> sXUIPaths;
static LLFrameTimer sMouseIdleTimer;
+ static add_popup_t sAddPopupFunc;
+ static remove_popup_t sRemovePopupFunc;
+ static clear_popups_t sClearPopupsFunc;
};
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 63e627ceb5..d34083a384 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -73,9 +73,9 @@ S32 LLView::sLastBottomXML = S32_MIN;
std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack;
-#if LL_DEBUG
+//#if LL_DEBUG
BOOL LLView::sIsDrawing = FALSE;
-#endif
+//#endif
// Compiler optimization, generate extern template
template class LLView* LLView::getChild<class LLView>(
@@ -150,6 +150,10 @@ LLView::~LLView()
{
dirtyRect();
//llinfos << "Deleting view " << mName << ":" << (void*) this << llendl;
+ if (LLView::sIsDrawing)
+ {
+ llwarns << "Deleting view " << mName << " during UI draw() phase" << llendl;
+ }
// llassert(LLView::sIsDrawing == FALSE);
// llassert_always(sDepth == 0); // avoid deleting views while drawing! It can subtly break list iterators
@@ -592,11 +596,6 @@ void LLView::setVisible(BOOL visible)
{
if ( mVisible != visible )
{
- if( !visible && (gFocusMgr.getTopCtrl() == this) )
- {
- gFocusMgr.setTopCtrl( NULL );
- }
-
mVisible = visible;
// notify children of visibility change if root, or part of visible hierarchy
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index c4d7313743..efae00f0e5 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -171,9 +171,9 @@ private:
// widgets in general are not copyable
LLView(const LLView& other) {};
public:
-#if LL_DEBUG
+//#if LL_DEBUG
static BOOL sIsDrawing;
-#endif
+//#endif
enum ESoundFlags
{
SILENT = 0,