aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/lluictrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llui/lluictrl.cpp360
1 files changed, 360 insertions, 0 deletions
diff --git a/linden/indra/llui/lluictrl.cpp b/linden/indra/llui/lluictrl.cpp
new file mode 100644
index 0000000..977f523
--- /dev/null
+++ b/linden/indra/llui/lluictrl.cpp
@@ -0,0 +1,360 @@
1/**
2 * @file lluictrl.cpp
3 * @author James Cook, Richard Nelson, Tom Yedwab
4 * @brief Abstract base class for UI controls
5 *
6 * Copyright (c) 2001-2007, Linden Research, Inc.
7 *
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29//#include "llviewerprecompiledheaders.h"
30#include "linden_common.h"
31
32#include "lluictrl.h"
33
34#include "llgl.h"
35#include "llui.h"
36#include "lluiconstants.h"
37#include "llfocusmgr.h"
38#include "v3color.h"
39
40#include "llstring.h"
41#include "llfontgl.h"
42#include "llkeyboard.h"
43
44const U32 MAX_STRING_LENGTH = 10;
45
46LLUICtrl::LLUICtrl() :
47 mCommitCallback(NULL),
48 mFocusReceivedCallback(NULL),
49 mFocusChangedCallback(NULL),
50 mValidateCallback(NULL),
51 mCallbackUserData(NULL),
52 mTentative(FALSE),
53 mTabStop(TRUE),
54 mIsChrome(FALSE)
55{
56}
57
58LLUICtrl::LLUICtrl(const LLString& name, const LLRect& rect, BOOL mouse_opaque,
59 void (*on_commit_callback)(LLUICtrl*, void*),
60 void* callback_userdata,
61 U32 reshape)
62: // can't make this automatically follow top and left, breaks lots
63 // of buttons in the UI. JC 7/20/2002
64 LLView( name, rect, mouse_opaque, reshape ),
65 mCommitCallback( on_commit_callback) ,
66 mFocusReceivedCallback( NULL ),
67 mFocusChangedCallback( NULL ),
68 mValidateCallback( NULL ),
69 mCallbackUserData( callback_userdata ),
70 mTentative( FALSE ),
71 mTabStop( TRUE ),
72 mIsChrome(FALSE)
73{
74}
75
76LLUICtrl::~LLUICtrl()
77{
78 gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
79}
80
81void LLUICtrl::onCommit()
82{
83 if( mCommitCallback )
84 {
85 mCommitCallback( this, mCallbackUserData );
86 }
87}
88
89// virtual
90BOOL LLUICtrl::setTextArg( const LLString& key, const LLString& text )
91{
92 return FALSE;
93}
94
95// virtual
96BOOL LLUICtrl::setLabelArg( const LLString& key, const LLString& text )
97{
98 return FALSE;
99}
100
101// virtual
102LLCtrlSelectionInterface* LLUICtrl::getSelectionInterface()
103{
104 return NULL;
105}
106
107// virtual
108LLCtrlListInterface* LLUICtrl::getListInterface()
109{
110 return NULL;
111}
112
113// virtual
114LLCtrlScrollInterface* LLUICtrl::getScrollInterface()
115{
116 return NULL;
117}
118
119// virtual
120void LLUICtrl::setTabStop( BOOL b )
121{
122 mTabStop = b;
123}
124
125// virtual
126BOOL LLUICtrl::hasTabStop() const
127{
128 return mTabStop;
129}
130
131// virtual
132BOOL LLUICtrl::acceptsTextInput() const
133{
134 return FALSE;
135}
136
137// virtual
138void LLUICtrl::onTabInto()
139{
140}
141
142// virtual
143void LLUICtrl::clear()
144{
145}
146
147// virtual
148void LLUICtrl::setIsChrome(BOOL is_chrome)
149{
150 mIsChrome = is_chrome;
151}
152
153// virtual
154BOOL LLUICtrl::getIsChrome() const
155{
156 return mIsChrome;
157}
158
159void LLUICtrl::onFocusReceived()
160{
161 if( mFocusReceivedCallback )
162 {
163 mFocusReceivedCallback( this, mCallbackUserData );
164 }
165 if( mFocusChangedCallback )
166 {
167 mFocusChangedCallback( this, mCallbackUserData );
168 }
169}
170
171void LLUICtrl::onFocusLost()
172{
173 if( mFocusChangedCallback )
174 {
175 mFocusChangedCallback( this, mCallbackUserData );
176 }
177}
178
179BOOL LLUICtrl::hasFocus() const
180{
181 return (gFocusMgr.childHasKeyboardFocus(this));
182}
183
184void LLUICtrl::setFocus(BOOL b)
185{
186 // focus NEVER goes to ui ctrls that are disabled!
187 if (!mEnabled)
188 {
189 return;
190 }
191 if( b )
192 {
193 if (!hasFocus())
194 {
195 gFocusMgr.setKeyboardFocus( this, &LLUICtrl::onFocusLostCallback );
196 onFocusReceived();
197 }
198 }
199 else
200 {
201 if( gFocusMgr.childHasKeyboardFocus(this))
202 {
203 gFocusMgr.setKeyboardFocus( NULL, NULL );
204 onFocusLost();
205 }
206 }
207}
208
209// static
210void LLUICtrl::onFocusLostCallback( LLUICtrl* old_focus )
211{
212 old_focus->onFocusLost();
213}
214
215// this comparator uses the crazy disambiguating logic of LLCompareByTabOrder,
216// but to switch up the order so that children that have the default tab group come first
217// and those that are prior to the default tab group come last
218class CompareByDefaultTabGroup: public LLCompareByTabOrder
219{
220public:
221 CompareByDefaultTabGroup(LLView::child_tab_order_t order, S32 default_tab_group):
222 LLCompareByTabOrder(order),
223 mDefaultTabGroup(default_tab_group) {}
224protected:
225 /*virtual*/ bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const
226 {
227 S32 ag = a.first; // tab group for a
228 S32 bg = b.first; // tab group for b
229 // these two ifs have the effect of moving elements prior to the default tab group to the end of the list
230 // (still sorted relative to each other, though)
231 if(ag < mDefaultTabGroup && bg >= mDefaultTabGroup) return false;
232 if(bg < mDefaultTabGroup && ag >= mDefaultTabGroup) return true;
233 return a < b; // sort correctly if they're both on the same side of the default tab group
234 }
235 S32 mDefaultTabGroup;
236};
237
238// sorter for plugging into the query
239class DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton<DefaultTabGroupFirstSorter>
240{
241public:
242 /*virtual*/ void operator() (LLView * parent, viewList_t &children) const
243 {
244 children.sort(CompareByDefaultTabGroup(parent->getCtrlOrder(), parent->getDefaultTabGroup()));
245 }
246};
247
248BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields)
249{
250 // try to select default tab group child
251 LLCtrlQuery query = LLView::getTabOrderQuery();
252 // sort things such that the default tab group is at the front
253 query.setSorter(DefaultTabGroupFirstSorter::getInstance());
254 LLView::child_list_t result = query(this);
255 if(result.size() > 0)
256 {
257 LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front());
258 if(!ctrl->hasFocus())
259 {
260 ctrl->setFocus(TRUE);
261 ctrl->onTabInto();
262 gFocusMgr.triggerFocusFlash();
263 }
264 return TRUE;
265 }
266 // fall back on default behavior if we didn't find anything
267 return LLView::focusFirstItem(prefer_text_fields);
268}
269
270/*
271// Don't let the children handle the tool tip. Handle it here instead.
272BOOL LLUICtrl::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen)
273{
274 BOOL handled = FALSE;
275 if (getVisible() && pointInView( x, y ) )
276 {
277 if( !mToolTipMsg.empty() )
278 {
279 msg = mToolTipMsg;
280
281 // Convert rect local to screen coordinates
282 localPointToScreen(
283 0, 0,
284 &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
285 localPointToScreen(
286 mRect.getWidth(), mRect.getHeight(),
287 &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) );
288
289 handled = TRUE;
290 }
291 }
292
293 if (!handled)
294 {
295 return LLView::handleToolTip(x, y, msg, sticky_rect_screen);
296 }
297
298 return handled;
299}*/
300
301void LLUICtrl::initFromXML(LLXMLNodePtr node, LLView* parent)
302{
303 BOOL has_tab_stop = hasTabStop();
304 node->getAttributeBOOL("tab_stop", has_tab_stop);
305
306 setTabStop(has_tab_stop);
307
308 LLView::initFromXML(node, parent);
309}
310
311LLXMLNodePtr LLUICtrl::getXML(bool save_children) const
312{
313 LLXMLNodePtr node = LLView::getXML(save_children);
314 node->createChild("tab_stop", TRUE)->setBoolValue(hasTabStop());
315
316 return node;
317}
318
319// *NOTE: If other classes derive from LLPanel, they will need to be
320// added to this function.
321LLPanel* LLUICtrl::getParentPanel() const
322{
323 LLView* parent = getParent();
324 while (parent
325 && parent->getWidgetType() != WIDGET_TYPE_PANEL
326 && parent->getWidgetType() != WIDGET_TYPE_FLOATER)
327 {
328 parent = parent->getParent();
329 }
330 return reinterpret_cast<LLPanel*>(parent);
331}
332
333// virtual
334void LLUICtrl::setTentative(BOOL b)
335{
336 mTentative = b;
337}
338
339// virtual
340BOOL LLUICtrl::getTentative() const
341{
342 return mTentative;
343}
344
345// virtual
346void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) )
347{
348}
349
350// virtual
351void LLUICtrl::setColor(const LLColor4& color)
352{ }
353
354// virtual
355void LLUICtrl::setMinValue(LLSD min_value)
356{ }
357
358// virtual
359void LLUICtrl::setMaxValue(LLSD max_value)
360{ }