summaryrefslogtreecommitdiff
path: root/indra/llui/lluictrl.cpp
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
committerJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
commit420b91db29485df39fd6e724e782c449158811cb (patch)
treeb471a94563af914d3ed3edd3e856d21cb1b69945 /indra/llui/lluictrl.cpp
Print done when done.
Diffstat (limited to 'indra/llui/lluictrl.cpp')
-rw-r--r--indra/llui/lluictrl.cpp341
1 files changed, 341 insertions, 0 deletions
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
new file mode 100644
index 0000000000..0d9791c660
--- /dev/null
+++ b/indra/llui/lluictrl.cpp
@@ -0,0 +1,341 @@
+/**
+ * @file lluictrl.cpp
+ * @author James Cook, Richard Nelson, Tom Yedwab
+ * @brief Abstract base class for UI controls
+ *
+ * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+//#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
+
+#include "lluictrl.h"
+
+#include "llgl.h"
+#include "llui.h"
+#include "lluiconstants.h"
+#include "llfocusmgr.h"
+#include "v3color.h"
+
+#include "llstring.h"
+#include "llfontgl.h"
+#include "llkeyboard.h"
+
+const U32 MAX_STRING_LENGTH = 10;
+
+LLUICtrl::LLUICtrl() :
+ mCommitCallback(NULL),
+ mFocusReceivedCallback(NULL),
+ mFocusChangedCallback(NULL),
+ mValidateCallback(NULL),
+ mCallbackUserData(NULL),
+ mTentative(FALSE),
+ mTabStop(TRUE),
+ mIsChrome(FALSE)
+{
+}
+
+LLUICtrl::LLUICtrl(const LLString& name, const LLRect& rect, BOOL mouse_opaque,
+ void (*on_commit_callback)(LLUICtrl*, void*),
+ void* callback_userdata,
+ U32 reshape)
+: // can't make this automatically follow top and left, breaks lots
+ // of buttons in the UI. JC 7/20/2002
+ LLView( name, rect, mouse_opaque, reshape ),
+ mCommitCallback( on_commit_callback) ,
+ mFocusReceivedCallback( NULL ),
+ mFocusChangedCallback( NULL ),
+ mValidateCallback( NULL ),
+ mCallbackUserData( callback_userdata ),
+ mTentative( FALSE ),
+ mTabStop( TRUE ),
+ mIsChrome(FALSE)
+{
+}
+
+LLUICtrl::~LLUICtrl()
+{
+ gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+}
+
+void LLUICtrl::onCommit()
+{
+ if( mCommitCallback )
+ {
+ mCommitCallback( this, mCallbackUserData );
+ }
+}
+
+// virtual
+BOOL LLUICtrl::setTextArg( const LLString& key, const LLString& text )
+{
+ return FALSE;
+}
+
+// virtual
+BOOL LLUICtrl::setLabelArg( const LLString& key, const LLString& text )
+{
+ return FALSE;
+}
+
+// virtual
+LLCtrlSelectionInterface* LLUICtrl::getSelectionInterface()
+{
+ return NULL;
+}
+
+// virtual
+LLCtrlListInterface* LLUICtrl::getListInterface()
+{
+ return NULL;
+}
+
+// virtual
+LLCtrlScrollInterface* LLUICtrl::getScrollInterface()
+{
+ return NULL;
+}
+
+// virtual
+void LLUICtrl::setTabStop( BOOL b )
+{
+ mTabStop = b;
+}
+
+// virtual
+BOOL LLUICtrl::hasTabStop() const
+{
+ return mTabStop;
+}
+
+// virtual
+BOOL LLUICtrl::acceptsTextInput() const
+{
+ return FALSE;
+}
+
+// virtual
+void LLUICtrl::onTabInto()
+{
+}
+
+// virtual
+void LLUICtrl::clear()
+{
+}
+
+// virtual
+void LLUICtrl::setIsChrome(BOOL is_chrome)
+{
+ mIsChrome = is_chrome;
+}
+
+// virtual
+BOOL LLUICtrl::getIsChrome() const
+{
+ return mIsChrome;
+}
+
+void LLUICtrl::onFocusReceived()
+{
+ if( mFocusReceivedCallback )
+ {
+ mFocusReceivedCallback( this, mCallbackUserData );
+ }
+ if( mFocusChangedCallback )
+ {
+ mFocusChangedCallback( this, mCallbackUserData );
+ }
+}
+
+void LLUICtrl::onFocusLost()
+{
+ if( mFocusChangedCallback )
+ {
+ mFocusChangedCallback( this, mCallbackUserData );
+ }
+}
+
+BOOL LLUICtrl::hasFocus() const
+{
+ return (gFocusMgr.childHasKeyboardFocus(this));
+}
+
+void LLUICtrl::setFocus(BOOL b)
+{
+ // focus NEVER goes to ui ctrls that are disabled!
+ if (!mEnabled)
+ {
+ return;
+ }
+ if( b )
+ {
+ if (!hasFocus())
+ {
+ gFocusMgr.setKeyboardFocus( this, &LLUICtrl::onFocusLostCallback );
+ onFocusReceived();
+ }
+ }
+ else
+ {
+ if( gFocusMgr.childHasKeyboardFocus(this))
+ {
+ gFocusMgr.setKeyboardFocus( NULL, NULL );
+ onFocusLost();
+ }
+ }
+}
+
+// static
+void LLUICtrl::onFocusLostCallback( LLUICtrl* old_focus )
+{
+ old_focus->onFocusLost();
+}
+
+// this comparator uses the crazy disambiguating logic of LLCompareByTabOrder,
+// but to switch up the order so that children that have the default tab group come first
+// and those that are prior to the default tab group come last
+class CompareByDefaultTabGroup: public LLCompareByTabOrder
+{
+public:
+ CompareByDefaultTabGroup(LLView::child_tab_order_t order, S32 default_tab_group):
+ LLCompareByTabOrder(order),
+ mDefaultTabGroup(default_tab_group) {}
+protected:
+ /*virtual*/ bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const
+ {
+ S32 ag = a.first; // tab group for a
+ S32 bg = b.first; // tab group for b
+ // these two ifs have the effect of moving elements prior to the default tab group to the end of the list
+ // (still sorted relative to each other, though)
+ if(ag < mDefaultTabGroup && bg >= mDefaultTabGroup) return false;
+ if(bg < mDefaultTabGroup && ag >= mDefaultTabGroup) return true;
+ return a < b; // sort correctly if they're both on the same side of the default tab group
+ }
+ S32 mDefaultTabGroup;
+};
+
+// sorter for plugging into the query
+class DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton<DefaultTabGroupFirstSorter>
+{
+public:
+ /*virtual*/ void operator() (LLView * parent, viewList_t &children) const
+ {
+ children.sort(CompareByDefaultTabGroup(parent->getCtrlOrder(), parent->getDefaultTabGroup()));
+ }
+};
+
+BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields)
+{
+ // try to select default tab group child
+ LLCtrlQuery query = LLView::getTabOrderQuery();
+ // sort things such that the default tab group is at the front
+ query.setSorter(DefaultTabGroupFirstSorter::getInstance());
+ LLView::child_list_t result = query(this);
+ if(result.size() > 0)
+ {
+ LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front());
+ if(!ctrl->hasFocus())
+ {
+ ctrl->setFocus(TRUE);
+ ctrl->onTabInto();
+ gFocusMgr.triggerFocusFlash();
+ }
+ return TRUE;
+ }
+ // fall back on default behavior if we didn't find anything
+ return LLView::focusFirstItem(prefer_text_fields);
+}
+
+/*
+// Don't let the children handle the tool tip. Handle it here instead.
+BOOL LLUICtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen)
+{
+ BOOL handled = FALSE;
+ if (getVisible() && pointInView( x, y ) )
+ {
+ if( !mToolTipMsg.empty() )
+ {
+ msg = mToolTipMsg;
+
+ // Convert rect local to screen coordinates
+ localPointToScreen(
+ 0, 0,
+ &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
+ localPointToScreen(
+ mRect.getWidth(), mRect.getHeight(),
+ &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) );
+
+ handled = TRUE;
+ }
+ }
+
+ if (!handled)
+ {
+ return LLView::handleToolTip(x, y, msg, sticky_rect_screen);
+ }
+
+ return handled;
+}*/
+
+void LLUICtrl::initFromXML(LLXMLNodePtr node, LLView* parent)
+{
+ BOOL has_tab_stop = hasTabStop();
+ node->getAttributeBOOL("tab_stop", has_tab_stop);
+
+ setTabStop(has_tab_stop);
+
+ LLView::initFromXML(node, parent);
+}
+
+LLXMLNodePtr LLUICtrl::getXML(bool save_children) const
+{
+ LLXMLNodePtr node = LLView::getXML(save_children);
+ node->createChild("tab_stop", TRUE)->setBoolValue(hasTabStop());
+
+ return node;
+}
+
+// *NOTE: If other classes derive from LLPanel, they will need to be
+// added to this function.
+LLPanel* LLUICtrl::getParentPanel() const
+{
+ LLView* parent = getParent();
+ while (parent
+ && parent->getWidgetType() != WIDGET_TYPE_PANEL
+ && parent->getWidgetType() != WIDGET_TYPE_FLOATER)
+ {
+ parent = parent->getParent();
+ }
+ return reinterpret_cast<LLPanel*>(parent);
+}
+
+// virtual
+void LLUICtrl::setTentative(BOOL b)
+{
+ mTentative = b;
+}
+
+// virtual
+BOOL LLUICtrl::getTentative() const
+{
+ return mTentative;
+}
+
+// virtual
+void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) )
+{
+}
+
+// virtual
+void LLUICtrl::setColor(const LLColor4& color)
+{ }
+
+// virtual
+void LLUICtrl::setMinValue(LLSD min_value)
+{ }
+
+// virtual
+void LLUICtrl::setMaxValue(LLSD max_value)
+{ }