diff options
author | Jacek Antonelli | 2011-05-08 15:13:37 -0500 |
---|---|---|
committer | Jacek Antonelli | 2011-05-08 15:50:49 -0500 |
commit | 7278f0254a3944bd2bcbf1e855fb0d90c3086a27 (patch) | |
tree | 5d7ecb81ebf1a07482f0a7d3d13acd7f18360c0b /linden/indra/llui | |
parent | Imprudence 1.3.1 released. (diff) | |
parent | Changed version to Experimental 2011.04.19 (diff) | |
download | meta-impy-7278f0254a3944bd2bcbf1e855fb0d90c3086a27.zip meta-impy-7278f0254a3944bd2bcbf1e855fb0d90c3086a27.tar.gz meta-impy-7278f0254a3944bd2bcbf1e855fb0d90c3086a27.tar.bz2 meta-impy-7278f0254a3944bd2bcbf1e855fb0d90c3086a27.tar.xz |
Merged Experimental branch (exp) back into main line (next).
Git thought many files (almost 100) had merge conflicts. But, after
resolving the conflicts (which were mostly trivial), almost all the
files turned out to be the same as in the exp branch. So, the
conflicts are not listed here. Check the diff between commit 244ffe8
and this commit to see what really changed.
Diffstat (limited to 'linden/indra/llui')
40 files changed, 2365 insertions, 418 deletions
diff --git a/linden/indra/llui/CMakeLists.txt b/linden/indra/llui/CMakeLists.txt index a0f80b4..e6b3b63 100644 --- a/linden/indra/llui/CMakeLists.txt +++ b/linden/indra/llui/CMakeLists.txt | |||
@@ -3,11 +3,9 @@ | |||
3 | project(llui) | 3 | project(llui) |
4 | 4 | ||
5 | include(00-Common) | 5 | include(00-Common) |
6 | include(LLAudio) | ||
7 | include(LLCommon) | 6 | include(LLCommon) |
8 | include(LLImage) | 7 | include(LLImage) |
9 | include(LLMath) | 8 | include(LLMath) |
10 | include(LLMedia) | ||
11 | include(LLMessage) | 9 | include(LLMessage) |
12 | include(LLRender) | 10 | include(LLRender) |
13 | include(LLWindow) | 11 | include(LLWindow) |
@@ -15,11 +13,9 @@ include(LLVFS) | |||
15 | include(LLXML) | 13 | include(LLXML) |
16 | 14 | ||
17 | include_directories( | 15 | include_directories( |
18 | ${LLAUDIO_INCLUDE_DIRS} | ||
19 | ${LLCOMMON_INCLUDE_DIRS} | 16 | ${LLCOMMON_INCLUDE_DIRS} |
20 | ${LLIMAGE_INCLUDE_DIRS} | 17 | ${LLIMAGE_INCLUDE_DIRS} |
21 | ${LLMATH_INCLUDE_DIRS} | 18 | ${LLMATH_INCLUDE_DIRS} |
22 | ${LLMEDIA_INCLUDE_DIRS} | ||
23 | ${LLMESSAGE_INCLUDE_DIRS} | 19 | ${LLMESSAGE_INCLUDE_DIRS} |
24 | ${LLRENDER_INCLUDE_DIRS} | 20 | ${LLRENDER_INCLUDE_DIRS} |
25 | ${LLWINDOW_INCLUDE_DIRS} | 21 | ${LLWINDOW_INCLUDE_DIRS} |
@@ -141,3 +137,14 @@ set_source_files_properties(${llui_HEADER_FILES} | |||
141 | list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES}) | 137 | list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES}) |
142 | 138 | ||
143 | add_library (llui ${llui_SOURCE_FILES}) | 139 | add_library (llui ${llui_SOURCE_FILES}) |
140 | # Libraries on which this library depends, needed for Linux builds | ||
141 | # Sort by high-level to low-level | ||
142 | target_link_libraries(llui | ||
143 | llrender | ||
144 | llwindow | ||
145 | llimage | ||
146 | llvfs # ugh, just for LLDir | ||
147 | llxml | ||
148 | llcommon # must be after llimage, llwindow, llrender | ||
149 | llmath | ||
150 | ) | ||
diff --git a/linden/indra/llui/llbutton.cpp b/linden/indra/llui/llbutton.cpp index 1a6c705..702e34e 100644 --- a/linden/indra/llui/llbutton.cpp +++ b/linden/indra/llui/llbutton.cpp | |||
@@ -840,6 +840,11 @@ void LLButton::setColor(const LLColor4& color) | |||
840 | setImageColor(color); | 840 | setImageColor(color); |
841 | } | 841 | } |
842 | 842 | ||
843 | void LLButton::setAlpha(F32 alpha) | ||
844 | { | ||
845 | mImageColor.setAlpha(alpha); | ||
846 | mDisabledImageColor.setAlpha(alpha * 0.5f); | ||
847 | } | ||
843 | 848 | ||
844 | void LLButton::setImageDisabled(LLPointer<LLUIImage> image) | 849 | void LLButton::setImageDisabled(LLPointer<LLUIImage> image) |
845 | { | 850 | { |
diff --git a/linden/indra/llui/llbutton.h b/linden/indra/llui/llbutton.h index 724b775..2174d95 100644 --- a/linden/indra/llui/llbutton.h +++ b/linden/indra/llui/llbutton.h | |||
@@ -136,7 +136,8 @@ public: | |||
136 | 136 | ||
137 | void setImageColor(const std::string& color_control); | 137 | void setImageColor(const std::string& color_control); |
138 | void setImageColor(const LLColor4& c); | 138 | void setImageColor(const LLColor4& c); |
139 | virtual void setColor(const LLColor4& c); | 139 | /*virtual*/ void setColor(const LLColor4& c); |
140 | /*virtual*/ void setAlpha(F32 alpha); | ||
140 | 141 | ||
141 | void setImages(const std::string &image_name, const std::string &selected_name); | 142 | void setImages(const std::string &image_name, const std::string &selected_name); |
142 | void setDisabledImages(const std::string &image_name, const std::string &selected_name); | 143 | void setDisabledImages(const std::string &image_name, const std::string &selected_name); |
diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp index be34325..f3ef83e 100644 --- a/linden/indra/llui/llcombobox.cpp +++ b/linden/indra/llui/llcombobox.cpp | |||
@@ -43,6 +43,7 @@ | |||
43 | 43 | ||
44 | // newview includes | 44 | // newview includes |
45 | #include "llbutton.h" | 45 | #include "llbutton.h" |
46 | #include "llfont.h" | ||
46 | #include "llkeyboard.h" | 47 | #include "llkeyboard.h" |
47 | #include "llscrolllistctrl.h" | 48 | #include "llscrolllistctrl.h" |
48 | #include "llwindow.h" | 49 | #include "llwindow.h" |
@@ -60,7 +61,7 @@ S32 MAX_COMBO_WIDTH = 500; | |||
60 | 61 | ||
61 | static LLRegisterWidget<LLComboBox> r1("combo_box"); | 62 | static LLRegisterWidget<LLComboBox> r1("combo_box"); |
62 | 63 | ||
63 | LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::string& label, | 64 | LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::string& label, const LLFontGL* font, |
64 | void (*commit_callback)(LLUICtrl*,void*), | 65 | void (*commit_callback)(LLUICtrl*,void*), |
65 | void *callback_userdata | 66 | void *callback_userdata |
66 | ) | 67 | ) |
@@ -76,6 +77,15 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std:: | |||
76 | mTextEntryCallback( NULL ), | 77 | mTextEntryCallback( NULL ), |
77 | mLabel(label) | 78 | mLabel(label) |
78 | { | 79 | { |
80 | if (font) | ||
81 | { | ||
82 | mGLFont = font; | ||
83 | } | ||
84 | else | ||
85 | { | ||
86 | mGLFont = LLFontGL::getFontSansSerifSmall(); | ||
87 | } | ||
88 | |||
79 | // Always use text box | 89 | // Always use text box |
80 | // Text label button | 90 | // Text label button |
81 | mButton = new LLButton(mLabel, | 91 | mButton = new LLButton(mLabel, |
@@ -89,14 +99,14 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std:: | |||
89 | mButton->setScaleImage(TRUE); | 99 | mButton->setScaleImage(TRUE); |
90 | 100 | ||
91 | mButton->setMouseDownCallback(onButtonDown); | 101 | mButton->setMouseDownCallback(onButtonDown); |
92 | mButton->setFont(LLFontGL::getFontSansSerifSmall()); | 102 | mButton->setFont(mGLFont); |
93 | mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); | 103 | mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT); |
94 | mButton->setHAlign( LLFontGL::LEFT ); | 104 | mButton->setHAlign( LLFontGL::LEFT ); |
95 | mButton->setRightHPad(2); | 105 | mButton->setRightHPad(2); |
96 | addChild(mButton); | 106 | addChild(mButton); |
97 | 107 | ||
98 | // disallow multiple selection | 108 | // disallow multiple selection |
99 | mList = new LLScrollListCtrl(std::string("ComboBox"), LLRect(), | 109 | mList = new LLScrollListCtrl(std::string("ComboBox"), LLRect(), mGLFont, |
100 | &LLComboBox::onItemSelected, this, FALSE); | 110 | &LLComboBox::onItemSelected, this, FALSE); |
101 | mList->setVisible(FALSE); | 111 | mList->setVisible(FALSE); |
102 | mList->setBgWriteableColor( LLColor4(1,1,1,1) ); | 112 | mList->setBgWriteableColor( LLColor4(1,1,1,1) ); |
@@ -167,11 +177,14 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * | |||
167 | S32 max_chars = 20; | 177 | S32 max_chars = 20; |
168 | node->getAttributeS32("max_chars", max_chars); | 178 | node->getAttributeS32("max_chars", max_chars); |
169 | 179 | ||
180 | LLFontGL* font = LLView::selectFont(node); | ||
181 | |||
170 | LLUICtrlCallback callback = NULL; | 182 | LLUICtrlCallback callback = NULL; |
171 | 183 | ||
172 | LLComboBox* combo_box = new LLComboBox(name, | 184 | LLComboBox* combo_box = new LLComboBox(name, |
173 | rect, | 185 | rect, |
174 | label, | 186 | label, |
187 | font, | ||
175 | callback, | 188 | callback, |
176 | NULL); | 189 | NULL); |
177 | combo_box->setAllowTextEntry(allow_text_entry, max_chars); | 190 | combo_box->setAllowTextEntry(allow_text_entry, max_chars); |
@@ -540,7 +553,7 @@ void LLComboBox::updateLayout() | |||
540 | mTextEntry = new LLLineEditor(std::string("combo_text_entry"), | 553 | mTextEntry = new LLLineEditor(std::string("combo_text_entry"), |
541 | text_entry_rect, | 554 | text_entry_rect, |
542 | LLStringUtil::null, | 555 | LLStringUtil::null, |
543 | LLFontGL::getFontSansSerifSmall(), | 556 | mGLFont, |
544 | mMaxChars, | 557 | mMaxChars, |
545 | onTextCommit, | 558 | onTextCommit, |
546 | onTextEntry, | 559 | onTextEntry, |
@@ -578,6 +591,13 @@ void LLComboBox::updateLayout() | |||
578 | } | 591 | } |
579 | } | 592 | } |
580 | 593 | ||
594 | |||
595 | void LLComboBox::getAllData(std::vector<LLScrollListItem*>& item_list) const | ||
596 | { | ||
597 | item_list = mList->getAllData(); | ||
598 | } | ||
599 | |||
600 | |||
581 | void* LLComboBox::getCurrentUserdata() | 601 | void* LLComboBox::getCurrentUserdata() |
582 | { | 602 | { |
583 | LLScrollListItem* item = mList->getFirstSelected(); | 603 | LLScrollListItem* item = mList->getFirstSelected(); |
@@ -1153,7 +1173,7 @@ LLFlyoutButton::LLFlyoutButton( | |||
1153 | const std::string& label, | 1173 | const std::string& label, |
1154 | void (*commit_callback)(LLUICtrl*, void*) , | 1174 | void (*commit_callback)(LLUICtrl*, void*) , |
1155 | void *callback_userdata) | 1175 | void *callback_userdata) |
1156 | : LLComboBox(name, rect, LLStringUtil::null, commit_callback, callback_userdata), | 1176 | : LLComboBox(name, rect, LLStringUtil::null, NULL, commit_callback, callback_userdata), |
1157 | mToggleState(FALSE), | 1177 | mToggleState(FALSE), |
1158 | mActionButton(NULL) | 1178 | mActionButton(NULL) |
1159 | { | 1179 | { |
@@ -1214,6 +1234,8 @@ LLXMLNodePtr LLFlyoutButton::getXML(bool save_children) const | |||
1214 | } | 1234 | } |
1215 | } | 1235 | } |
1216 | 1236 | ||
1237 | node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont)); | ||
1238 | |||
1217 | return node; | 1239 | return node; |
1218 | } | 1240 | } |
1219 | 1241 | ||
diff --git a/linden/indra/llui/llcombobox.h b/linden/indra/llui/llcombobox.h index 95ad17a..f92fe44 100644 --- a/linden/indra/llui/llcombobox.h +++ b/linden/indra/llui/llcombobox.h | |||
@@ -67,7 +67,8 @@ public: | |||
67 | LLComboBox( | 67 | LLComboBox( |
68 | const std::string& name, | 68 | const std::string& name, |
69 | const LLRect &rect, | 69 | const LLRect &rect, |
70 | const std::string& label, | 70 | const std::string& label, |
71 | const LLFontGL* font = NULL, | ||
71 | void (*commit_callback)(LLUICtrl*, void*) = NULL, | 72 | void (*commit_callback)(LLUICtrl*, void*) = NULL, |
72 | void *callback_userdata = NULL | 73 | void *callback_userdata = NULL |
73 | ); | 74 | ); |
@@ -168,6 +169,7 @@ public: | |||
168 | 169 | ||
169 | //======================================================================== | 170 | //======================================================================== |
170 | 171 | ||
172 | void getAllData(std::vector<LLScrollListItem*>& item_list) const; | ||
171 | void* getCurrentUserdata(); | 173 | void* getCurrentUserdata(); |
172 | 174 | ||
173 | void setPrearrangeCallback( void (*cb)(LLUICtrl*,void*) ) { mPrearrangeCallback = cb; } | 175 | void setPrearrangeCallback( void (*cb)(LLUICtrl*,void*) ) { mPrearrangeCallback = cb; } |
@@ -190,6 +192,7 @@ protected: | |||
190 | EPreferredPosition mListPosition; | 192 | EPreferredPosition mListPosition; |
191 | LLPointer<LLUIImage> mArrowImage; | 193 | LLPointer<LLUIImage> mArrowImage; |
192 | std::string mLabel; | 194 | std::string mLabel; |
195 | const LLFontGL* mGLFont; | ||
193 | 196 | ||
194 | private: | 197 | private: |
195 | S32 mButtonPadding; | 198 | S32 mButtonPadding; |
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index f6451a1..bb42ca3 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp | |||
@@ -1459,9 +1459,9 @@ void LLFloater::draw() | |||
1459 | { | 1459 | { |
1460 | if (hasFocus() && getDefaultButton()->getEnabled()) | 1460 | if (hasFocus() && getDefaultButton()->getEnabled()) |
1461 | { | 1461 | { |
1462 | LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); | 1462 | LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); |
1463 | // is this button a direct descendent and not a nested widget (e.g. checkbox)? | 1463 | // is this button a direct descendent and not a nested widget (e.g. checkbox)? |
1464 | BOOL focus_is_child_button = dynamic_cast<LLButton*>(focus_ctrl) != NULL && focus_ctrl->getParent() == this; | 1464 | BOOL focus_is_child_button = dynamic_cast<LLButton*>(focus_ctrl) != NULL && dynamic_cast<LLButton*>(focus_ctrl)->getParent() == this; |
1465 | // only enable default button when current focus is not a button | 1465 | // only enable default button when current focus is not a button |
1466 | getDefaultButton()->setBorderEnabled(!focus_is_child_button); | 1466 | getDefaultButton()->setBorderEnabled(!focus_is_child_button); |
1467 | } | 1467 | } |
@@ -1481,7 +1481,7 @@ void LLFloater::draw() | |||
1481 | else | 1481 | else |
1482 | { | 1482 | { |
1483 | // draw children | 1483 | // draw children |
1484 | LLView* focused_child = gFocusMgr.getKeyboardFocus(); | 1484 | LLView* focused_child = dynamic_cast<LLView*>(gFocusMgr.getKeyboardFocus()); |
1485 | BOOL focused_child_visible = FALSE; | 1485 | BOOL focused_child_visible = FALSE; |
1486 | if (focused_child && focused_child->getParent() == this) | 1486 | if (focused_child && focused_child->getParent() == this) |
1487 | { | 1487 | { |
@@ -2239,7 +2239,7 @@ BOOL LLFloaterView::allChildrenClosed() | |||
2239 | LLView* viewp = *it; | 2239 | LLView* viewp = *it; |
2240 | LLFloater* floaterp = (LLFloater*)viewp; | 2240 | LLFloater* floaterp = (LLFloater*)viewp; |
2241 | 2241 | ||
2242 | if (floaterp->getVisible() && !floaterp->isDead() && floaterp->canClose()) | 2242 | if (floaterp->getVisible() && !floaterp->isDead() && floaterp->isCloseable()) |
2243 | { | 2243 | { |
2244 | return false; | 2244 | return false; |
2245 | } | 2245 | } |
diff --git a/linden/indra/llui/llfocusmgr.cpp b/linden/indra/llui/llfocusmgr.cpp index 661ffdd..96b01b9 100644 --- a/linden/indra/llui/llfocusmgr.cpp +++ b/linden/indra/llui/llfocusmgr.cpp | |||
@@ -38,6 +38,68 @@ | |||
38 | 38 | ||
39 | const F32 FOCUS_FADE_TIME = 0.3f; | 39 | const F32 FOCUS_FADE_TIME = 0.3f; |
40 | 40 | ||
41 | // NOTE: the LLFocusableElement implementation has been here from lluictrl.cpp. | ||
42 | |||
43 | LLFocusableElement::LLFocusableElement() | ||
44 | : mFocusLostCallback(NULL), | ||
45 | mFocusReceivedCallback(NULL), | ||
46 | mFocusChangedCallback(NULL), | ||
47 | mFocusCallbackUserData(NULL) | ||
48 | { | ||
49 | } | ||
50 | |||
51 | // virtual | ||
52 | BOOL LLFocusableElement::handleKey(KEY key, MASK mask, BOOL called_from_parent) | ||
53 | { | ||
54 | return FALSE; | ||
55 | } | ||
56 | |||
57 | // virtual | ||
58 | BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) | ||
59 | { | ||
60 | return FALSE; | ||
61 | } | ||
62 | |||
63 | // virtual | ||
64 | LLFocusableElement::~LLFocusableElement() | ||
65 | { | ||
66 | } | ||
67 | |||
68 | void LLFocusableElement::onFocusReceived() | ||
69 | { | ||
70 | if( mFocusReceivedCallback ) | ||
71 | { | ||
72 | mFocusReceivedCallback( this, mFocusCallbackUserData ); | ||
73 | } | ||
74 | if( mFocusChangedCallback ) | ||
75 | { | ||
76 | mFocusChangedCallback( this, mFocusCallbackUserData ); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | void LLFocusableElement::onFocusLost() | ||
81 | { | ||
82 | if( mFocusLostCallback ) | ||
83 | { | ||
84 | mFocusLostCallback( this, mFocusCallbackUserData ); | ||
85 | } | ||
86 | |||
87 | if( mFocusChangedCallback ) | ||
88 | { | ||
89 | mFocusChangedCallback( this, mFocusCallbackUserData ); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | BOOL LLFocusableElement::hasFocus() const | ||
94 | { | ||
95 | return gFocusMgr.getKeyboardFocus() == this; | ||
96 | } | ||
97 | |||
98 | void LLFocusableElement::setFocus(BOOL b) | ||
99 | { | ||
100 | } | ||
101 | |||
102 | |||
41 | LLFocusMgr gFocusMgr; | 103 | LLFocusMgr gFocusMgr; |
42 | 104 | ||
43 | LLFocusMgr::LLFocusMgr() | 105 | LLFocusMgr::LLFocusMgr() |
@@ -87,11 +149,13 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) | |||
87 | } | 149 | } |
88 | 150 | ||
89 | 151 | ||
90 | void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystrokes_only) | 152 | void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only) |
91 | { | 153 | { |
92 | if (mLockedView && | 154 | if (mLockedView && |
93 | (new_focus == NULL || | 155 | (new_focus == NULL || |
94 | (new_focus != mLockedView && !new_focus->hasAncestor(mLockedView)))) | 156 | (new_focus != mLockedView |
157 | && dynamic_cast<LLView*>(new_focus) | ||
158 | && !dynamic_cast<LLView*>(new_focus)->hasAncestor(mLockedView)))) | ||
95 | { | 159 | { |
96 | // don't allow focus to go to anything that is not the locked focus | 160 | // don't allow focus to go to anything that is not the locked focus |
97 | // or one of its descendants | 161 | // or one of its descendants |
@@ -121,7 +185,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke | |||
121 | mFocusTimer.reset(); | 185 | mFocusTimer.reset(); |
122 | 186 | ||
123 | #ifdef _DEBUG | 187 | #ifdef _DEBUG |
124 | mKeyboardFocusName = new_focus ? new_focus->getName() : std::string("none"); | 188 | LLUICtrl* focus_ctrl = dynamic_cast<LLUICtrl*>(new_focus); |
189 | mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none"); | ||
125 | #endif | 190 | #endif |
126 | 191 | ||
127 | // If we've got a default keyboard focus, and the caller is | 192 | // If we've got a default keyboard focus, and the caller is |
@@ -131,8 +196,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke | |||
131 | mDefaultKeyboardFocus->setFocus(TRUE); | 196 | mDefaultKeyboardFocus->setFocus(TRUE); |
132 | } | 197 | } |
133 | 198 | ||
134 | LLView* focus_subtree = mKeyboardFocus; | 199 | LLView* focus_subtree = dynamic_cast<LLView*>(mKeyboardFocus); |
135 | LLView* viewp = mKeyboardFocus; | 200 | LLView* viewp = dynamic_cast<LLView*>(mKeyboardFocus); |
136 | // find root-most focus root | 201 | // find root-most focus root |
137 | while(viewp) | 202 | while(viewp) |
138 | { | 203 | { |
@@ -146,7 +211,8 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke | |||
146 | 211 | ||
147 | if (focus_subtree) | 212 | if (focus_subtree) |
148 | { | 213 | { |
149 | mFocusHistory[focus_subtree->getHandle()] = mKeyboardFocus ? mKeyboardFocus->getHandle() : LLHandle<LLView>(); | 214 | LLView* focused_view = dynamic_cast<LLView*>(mKeyboardFocus); |
215 | mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>(); | ||
150 | } | 216 | } |
151 | } | 217 | } |
152 | 218 | ||
@@ -160,7 +226,7 @@ void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, BOOL lock, BOOL keystroke | |||
160 | // Returns TRUE is parent or any descedent of parent has keyboard focus. | 226 | // Returns TRUE is parent or any descedent of parent has keyboard focus. |
161 | BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const | 227 | BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const |
162 | { | 228 | { |
163 | LLView* focus_view = mKeyboardFocus; | 229 | LLView* focus_view = dynamic_cast<LLView*>(mKeyboardFocus); |
164 | while( focus_view ) | 230 | while( focus_view ) |
165 | { | 231 | { |
166 | if( focus_view == parent ) | 232 | if( focus_view == parent ) |
@@ -190,7 +256,7 @@ BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const | |||
190 | return FALSE; | 256 | return FALSE; |
191 | } | 257 | } |
192 | 258 | ||
193 | void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLView* focus ) | 259 | void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* focus ) |
194 | { | 260 | { |
195 | // should be ok to unlock here, as you have to know the locked view | 261 | // should be ok to unlock here, as you have to know the locked view |
196 | // in order to unlock it | 262 | // in order to unlock it |
@@ -313,7 +379,7 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view ) | |||
313 | 379 | ||
314 | void LLFocusMgr::lockFocus() | 380 | void LLFocusMgr::lockFocus() |
315 | { | 381 | { |
316 | mLockedView = mKeyboardFocus; | 382 | mLockedView = dynamic_cast<LLUICtrl*>(mKeyboardFocus); |
317 | } | 383 | } |
318 | 384 | ||
319 | void LLFocusMgr::unlockFocus() | 385 | void LLFocusMgr::unlockFocus() |
diff --git a/linden/indra/llui/llfocusmgr.h b/linden/indra/llui/llfocusmgr.h index aaeb25a..88ede1a 100644 --- a/linden/indra/llui/llfocusmgr.h +++ b/linden/indra/llui/llfocusmgr.h | |||
@@ -37,10 +37,39 @@ | |||
37 | 37 | ||
38 | #include "llstring.h" | 38 | #include "llstring.h" |
39 | #include "llframetimer.h" | 39 | #include "llframetimer.h" |
40 | #include "llview.h" | 40 | #include "llui.h" |
41 | 41 | ||
42 | class LLUICtrl; | 42 | class LLUICtrl; |
43 | class LLMouseHandler; | 43 | class LLMouseHandler; |
44 | class LLView; | ||
45 | |||
46 | class LLFocusableElement | ||
47 | { | ||
48 | friend class LLFocusMgr; // allow access to focus change handlers | ||
49 | public: | ||
50 | LLFocusableElement(); | ||
51 | virtual ~LLFocusableElement(); | ||
52 | |||
53 | virtual void setFocus( BOOL b ); | ||
54 | virtual BOOL hasFocus() const; | ||
55 | |||
56 | void setFocusLostCallback(void (*cb)(LLFocusableElement* caller, void*), void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; } | ||
57 | void setFocusReceivedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; } | ||
58 | void setFocusChangedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; } | ||
59 | |||
60 | // These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus. | ||
61 | virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); | ||
62 | virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); | ||
63 | |||
64 | protected: | ||
65 | virtual void onFocusReceived(); | ||
66 | virtual void onFocusLost(); | ||
67 | void (*mFocusLostCallback)( LLFocusableElement* caller, void* userdata ); | ||
68 | void (*mFocusReceivedCallback)( LLFocusableElement* ctrl, void* userdata ); | ||
69 | void (*mFocusChangedCallback)( LLFocusableElement* ctrl, void* userdata ); | ||
70 | void* mFocusCallbackUserData; | ||
71 | }; | ||
72 | |||
44 | 73 | ||
45 | class LLFocusMgr | 74 | class LLFocusMgr |
46 | { | 75 | { |
@@ -55,11 +84,11 @@ public: | |||
55 | BOOL childHasMouseCapture( const LLView* parent ) const; | 84 | BOOL childHasMouseCapture( const LLView* parent ) const; |
56 | 85 | ||
57 | // Keyboard Focus | 86 | // Keyboard Focus |
58 | void setKeyboardFocus(LLUICtrl* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus. | 87 | void setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock = FALSE, BOOL keystrokes_only = FALSE); // new_focus = NULL to release the focus. |
59 | LLUICtrl* getKeyboardFocus() const { return mKeyboardFocus; } | 88 | LLFocusableElement* getKeyboardFocus() const { return mKeyboardFocus; } |
60 | LLUICtrl* getLastKeyboardFocus() const { return mLastKeyboardFocus; } | 89 | LLFocusableElement* getLastKeyboardFocus() const { return mLastKeyboardFocus; } |
61 | BOOL childHasKeyboardFocus( const LLView* parent ) const; | 90 | BOOL childHasKeyboardFocus( const LLView* parent ) const; |
62 | void removeKeyboardFocusWithoutCallback( const LLView* focus ); | 91 | void removeKeyboardFocusWithoutCallback( const LLFocusableElement* focus ); |
63 | BOOL getKeystrokesOnly() { return mKeystrokesOnly; } | 92 | BOOL getKeystrokesOnly() { return mKeystrokesOnly; } |
64 | void setKeystrokesOnly(BOOL keystrokes_only) { mKeystrokesOnly = keystrokes_only; } | 93 | void setKeystrokesOnly(BOOL keystrokes_only) { mKeystrokesOnly = keystrokes_only; } |
65 | 94 | ||
@@ -75,8 +104,8 @@ public: | |||
75 | 104 | ||
76 | // If setKeyboardFocus(NULL) is called, and there is a non-NULL default | 105 | // If setKeyboardFocus(NULL) is called, and there is a non-NULL default |
77 | // keyboard focus view, focus goes there. JC | 106 | // keyboard focus view, focus goes there. JC |
78 | void setDefaultKeyboardFocus(LLUICtrl* default_focus) { mDefaultKeyboardFocus = default_focus; } | 107 | void setDefaultKeyboardFocus(LLFocusableElement* default_focus) { mDefaultKeyboardFocus = default_focus; } |
79 | LLUICtrl* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; } | 108 | LLFocusableElement* getDefaultKeyboardFocus() const { return mDefaultKeyboardFocus; } |
80 | 109 | ||
81 | 110 | ||
82 | // Top View | 111 | // Top View |
@@ -98,9 +127,9 @@ private: | |||
98 | LLMouseHandler* mMouseCaptor; // Mouse events are premptively routed to this object | 127 | LLMouseHandler* mMouseCaptor; // Mouse events are premptively routed to this object |
99 | 128 | ||
100 | // Keyboard Focus | 129 | // Keyboard Focus |
101 | LLUICtrl* mKeyboardFocus; // Keyboard events are preemptively routed to this object | 130 | LLFocusableElement* mKeyboardFocus; // Keyboard events are preemptively routed to this object |
102 | LLUICtrl* mLastKeyboardFocus; // who last had focus | 131 | LLFocusableElement* mLastKeyboardFocus; // who last had focus |
103 | LLUICtrl* mDefaultKeyboardFocus; | 132 | LLFocusableElement* mDefaultKeyboardFocus; |
104 | BOOL mKeystrokesOnly; | 133 | BOOL mKeystrokesOnly; |
105 | 134 | ||
106 | // Top View | 135 | // Top View |
diff --git a/linden/indra/llui/llfunctorregistry.cpp b/linden/indra/llui/llfunctorregistry.cpp index 0c5b165..5f9644f 100644 --- a/linden/indra/llui/llfunctorregistry.cpp +++ b/linden/indra/llui/llfunctorregistry.cpp | |||
@@ -31,6 +31,7 @@ | |||
31 | * $/LicenseInfo$ | 31 | * $/LicenseInfo$ |
32 | **/ | 32 | **/ |
33 | 33 | ||
34 | #include "linden_common.h" | ||
34 | #include "llfunctorregistry.h" | 35 | #include "llfunctorregistry.h" |
35 | 36 | ||
36 | // This is a default functor always resident in the system. | 37 | // This is a default functor always resident in the system. |
diff --git a/linden/indra/llui/lliconctrl.cpp b/linden/indra/llui/lliconctrl.cpp index e73c8fe..0df960e 100644 --- a/linden/indra/llui/lliconctrl.cpp +++ b/linden/indra/llui/lliconctrl.cpp | |||
@@ -112,6 +112,12 @@ void LLIconCtrl::draw() | |||
112 | LLUICtrl::draw(); | 112 | LLUICtrl::draw(); |
113 | } | 113 | } |
114 | 114 | ||
115 | // virtual | ||
116 | void LLIconCtrl::setAlpha(F32 alpha) | ||
117 | { | ||
118 | mColor.setAlpha(alpha); | ||
119 | } | ||
120 | |||
115 | // virtual | 121 | // virtual |
116 | void LLIconCtrl::setValue(const LLSD& value ) | 122 | void LLIconCtrl::setValue(const LLSD& value ) |
117 | { | 123 | { |
diff --git a/linden/indra/llui/lliconctrl.h b/linden/indra/llui/lliconctrl.h index 50778cf..2506fb2 100644 --- a/linden/indra/llui/lliconctrl.h +++ b/linden/indra/llui/lliconctrl.h | |||
@@ -65,6 +65,8 @@ public: | |||
65 | virtual void setValue(const LLSD& value ); | 65 | virtual void setValue(const LLSD& value ); |
66 | virtual LLSD getValue() const; | 66 | virtual LLSD getValue() const; |
67 | 67 | ||
68 | /*virtual*/ void setAlpha(F32 alpha); | ||
69 | |||
68 | void setColor(const LLColor4& color) { mColor = color; } | 70 | void setColor(const LLColor4& color) { mColor = color; } |
69 | 71 | ||
70 | virtual LLXMLNodePtr getXML(bool save_children = true) const; | 72 | virtual LLXMLNodePtr getXML(bool save_children = true) const; |
diff --git a/linden/indra/llui/lllineeditor.cpp b/linden/indra/llui/lllineeditor.cpp index 21f0800..453bb50 100644 --- a/linden/indra/llui/lllineeditor.cpp +++ b/linden/indra/llui/lllineeditor.cpp | |||
@@ -37,7 +37,6 @@ | |||
37 | #include "lllineeditor.h" | 37 | #include "lllineeditor.h" |
38 | 38 | ||
39 | #include "lltexteditor.h" | 39 | #include "lltexteditor.h" |
40 | #include "audioengine.h" | ||
41 | #include "llmath.h" | 40 | #include "llmath.h" |
42 | #include "llfontgl.h" | 41 | #include "llfontgl.h" |
43 | #include "llgl.h" | 42 | #include "llgl.h" |
@@ -56,12 +55,24 @@ | |||
56 | #include "llui.h" | 55 | #include "llui.h" |
57 | #include "lluictrlfactory.h" | 56 | #include "lluictrlfactory.h" |
58 | #include "llclipboard.h" | 57 | #include "llclipboard.h" |
58 | #include "llmemberlistener.h" | ||
59 | |||
60 | #include "../newview/lgghunspell_wrapper.h" | ||
61 | #include "../newview/lltranslate.h" | ||
62 | #include "../newview/llviewercontrol.h" | ||
63 | #include "../newview/lggautocorrect.h" | ||
64 | |||
59 | 65 | ||
60 | // | 66 | // |
61 | // Imported globals | 67 | // Imported globals |
62 | // | 68 | // |
63 | 69 | ||
64 | // | 70 | // |
71 | // Globals | ||
72 | |||
73 | |||
74 | |||
75 | // | ||
65 | // Constants | 76 | // Constants |
66 | // | 77 | // |
67 | 78 | ||
@@ -86,9 +97,41 @@ static LLRegisterWidget<LLLineEditor> r1("line_editor"); | |||
86 | 97 | ||
87 | /* static */ LLPointer<LLUIImage> LLLineEditor::sImage; | 98 | /* static */ LLPointer<LLUIImage> LLLineEditor::sImage; |
88 | 99 | ||
100 | typedef LLMemberListener<LLView> text_edit_listener_t; | ||
101 | |||
89 | // | 102 | // |
90 | // Member functions | 103 | // Member functions |
91 | // | 104 | // |
105 | class LineChatTranslationReceiver : public LLTranslate::TranslationReceiver | ||
106 | { | ||
107 | public : | ||
108 | LineChatTranslationReceiver(const std::string &toLang, LLLineEditor* line, const S32 start, const S32 len): | ||
109 | LLTranslate::TranslationReceiver("", toLang), | ||
110 | m_line(line), | ||
111 | m_position(start), | ||
112 | m_origLength(len) | ||
113 | { | ||
114 | } | ||
115 | |||
116 | static boost::intrusive_ptr<LineChatTranslationReceiver> build(const std::string &toLang,LLLineEditor* line, const S32 start, const S32 len) | ||
117 | { | ||
118 | return boost::intrusive_ptr<LineChatTranslationReceiver>(new LineChatTranslationReceiver(toLang, line, start, len)); | ||
119 | } | ||
120 | |||
121 | protected: | ||
122 | void handleResponse(const std::string &translation, const std::string &detectedLanguage) | ||
123 | { | ||
124 | m_line->translationReplace(translation, m_position, m_origLength); | ||
125 | } | ||
126 | void handleFailure() | ||
127 | { | ||
128 | LLTranslate::TranslationReceiver::handleFailure(); | ||
129 | } | ||
130 | private: | ||
131 | LLLineEditor* m_line; | ||
132 | S32 m_position; | ||
133 | S32 m_origLength; | ||
134 | }; | ||
92 | 135 | ||
93 | LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | 136 | LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, |
94 | const std::string& default_text, const LLFontGL* font, | 137 | const std::string& default_text, const LLFontGL* font, |
@@ -104,6 +147,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | |||
104 | : | 147 | : |
105 | LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ), | 148 | LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ), |
106 | mMaxLengthBytes(max_length_bytes), | 149 | mMaxLengthBytes(max_length_bytes), |
150 | mPopupMenuHandle(), | ||
107 | mCursorPos( 0 ), | 151 | mCursorPos( 0 ), |
108 | mScrollHPos( 0 ), | 152 | mScrollHPos( 0 ), |
109 | mTextPadLeft(0), | 153 | mTextPadLeft(0), |
@@ -118,6 +162,7 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | |||
118 | mLastSelectionY(-1), | 162 | mLastSelectionY(-1), |
119 | mLastSelectionStart(-1), | 163 | mLastSelectionStart(-1), |
120 | mLastSelectionEnd(-1), | 164 | mLastSelectionEnd(-1), |
165 | mLastContextMenuX(-1), | ||
121 | mPrevalidateFunc( prevalidate_func ), | 166 | mPrevalidateFunc( prevalidate_func ), |
122 | mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ), | 167 | mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ), |
123 | mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ), | 168 | mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ), |
@@ -137,7 +182,9 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | |||
137 | mReadOnly(FALSE), | 182 | mReadOnly(FALSE), |
138 | mHaveHistory(FALSE), | 183 | mHaveHistory(FALSE), |
139 | mImage( sImage ), | 184 | mImage( sImage ), |
140 | mReplaceNewlinesWithSpaces( TRUE ) | 185 | mReplaceNewlinesWithSpaces( TRUE ), |
186 | mSpellCheckable( FALSE ), | ||
187 | mAllowTranslate(TRUE) | ||
141 | { | 188 | { |
142 | llassert( max_length_bytes > 0 ); | 189 | llassert( max_length_bytes > 0 ); |
143 | 190 | ||
@@ -175,6 +222,19 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect, | |||
175 | sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga"); | 222 | sImage = LLUI::getUIImage("sm_rounded_corners_simple.tga"); |
176 | } | 223 | } |
177 | mImage = sImage; | 224 | mImage = sImage; |
225 | |||
226 | |||
227 | LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_rightclick_text.xml",this); | ||
228 | if (!menu) | ||
229 | { | ||
230 | menu = new LLMenuGL(LLStringUtil::null); | ||
231 | } | ||
232 | |||
233 | defineMenuCallbacks(menu); | ||
234 | mPopupMenuHandle = menu->getHandle(); | ||
235 | menu->setBorderColor(gColors.getColor("MenuItemDisabledColor")); | ||
236 | menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); | ||
237 | |||
178 | } | 238 | } |
179 | 239 | ||
180 | 240 | ||
@@ -188,6 +248,7 @@ LLLineEditor::~LLLineEditor() | |||
188 | { | 248 | { |
189 | gEditMenuHandler = NULL; | 249 | gEditMenuHandler = NULL; |
190 | } | 250 | } |
251 | LLView::deleteViewByHandle(mPopupMenuHandle); | ||
191 | } | 252 | } |
192 | 253 | ||
193 | 254 | ||
@@ -336,14 +397,23 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) | |||
336 | setCursor(llmin((S32)mText.length(), getCursor())); | 397 | setCursor(llmin((S32)mText.length(), getCursor())); |
337 | 398 | ||
338 | // Set current history line to end of history. | 399 | // Set current history line to end of history. |
339 | mCurrentHistoryLine = mLineHistory.end() - 1; | 400 | // RC Fix, its really not safe to just take 1 of the end itterator, if end==begin |
401 | // that leaves an invalid state upseting the secure STL checks | ||
402 | if(mLineHistory.empty()) | ||
403 | { | ||
404 | mCurrentHistoryLine = mLineHistory.begin(); | ||
405 | } | ||
406 | else | ||
407 | { | ||
408 | mCurrentHistoryLine = mLineHistory.end() - 1; | ||
409 | } | ||
340 | 410 | ||
341 | mPrevText = mText; | 411 | mPrevText = mText; |
342 | } | 412 | } |
343 | 413 | ||
344 | 414 | ||
345 | // Picks a new cursor position based on the actual screen size of text being drawn. | 415 | // Picks a new cursor position based on the actual screen size of text being drawn. |
346 | void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x ) | 416 | S32 LLLineEditor::calculateCursorFromMouse( S32 local_mouse_x ) const |
347 | { | 417 | { |
348 | const llwchar* wtext = mText.getWString().c_str(); | 418 | const llwchar* wtext = mText.getWString().c_str(); |
349 | LLWString asterix_text; | 419 | LLWString asterix_text; |
@@ -356,13 +426,17 @@ void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x ) | |||
356 | wtext = asterix_text.c_str(); | 426 | wtext = asterix_text.c_str(); |
357 | } | 427 | } |
358 | 428 | ||
359 | S32 cursor_pos = | 429 | return mScrollHPos + |
360 | mScrollHPos + | ||
361 | mGLFont->charFromPixelOffset( | 430 | mGLFont->charFromPixelOffset( |
362 | wtext, mScrollHPos, | 431 | wtext, mScrollHPos, |
363 | (F32)(local_mouse_x - mMinHPixels), | 432 | (F32)(local_mouse_x - mMinHPixels), |
364 | (F32)(mMaxHPixels - mMinHPixels + 1)); // min-max range is inclusive | 433 | (F32)(mMaxHPixels - mMinHPixels + 1)); // min-max range is inclusive |
365 | setCursor(cursor_pos); | 434 | |
435 | } | ||
436 | // Picks a new cursor position based on the actual screen size of text being drawn. | ||
437 | void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x ) | ||
438 | { | ||
439 | setCursor(calculateCursorFromMouse(local_mouse_x)); | ||
366 | } | 440 | } |
367 | 441 | ||
368 | void LLLineEditor::setCursor( S32 pos ) | 442 | void LLLineEditor::setCursor( S32 pos ) |
@@ -417,6 +491,188 @@ void LLLineEditor::deselect() | |||
417 | mIsSelecting = FALSE; | 491 | mIsSelecting = FALSE; |
418 | } | 492 | } |
419 | 493 | ||
494 | BOOL LLLineEditor::context_enable_cut(void* data) | ||
495 | { | ||
496 | LLLineEditor* line = (LLLineEditor*)data; | ||
497 | return (line && line->canCut()); | ||
498 | } | ||
499 | |||
500 | void LLLineEditor::context_cut(void* data) | ||
501 | { | ||
502 | LLLineEditor* line = (LLLineEditor*)data; | ||
503 | if(line)line->cut(); | ||
504 | } | ||
505 | |||
506 | BOOL LLLineEditor::context_enable_copy(void* data) | ||
507 | { | ||
508 | LLLineEditor* line = (LLLineEditor*)data; | ||
509 | return (line &&line->canCopy()); | ||
510 | } | ||
511 | |||
512 | void LLLineEditor::context_copy(void* data) | ||
513 | { | ||
514 | LLLineEditor* line = (LLLineEditor*)data; | ||
515 | if(line)line->copy(); | ||
516 | } | ||
517 | |||
518 | void LLLineEditor::spell_correct(void* data) | ||
519 | { | ||
520 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | ||
521 | LLLineEditor* line = tempBind->origin; | ||
522 | if(tempBind && line) | ||
523 | { | ||
524 | llinfos << ((LLMenuItemCallGL *)(tempBind->menuItem))->getName() << " : " << tempBind->origin->getName() << " : " << tempBind->word << llendl; | ||
525 | if(line)line->spellReplace(tempBind); | ||
526 | |||
527 | } | ||
528 | } | ||
529 | |||
530 | BOOL LLLineEditor::context_enable_translate(void* data) | ||
531 | { | ||
532 | LLLineEditor* line = (LLLineEditor*)data; | ||
533 | return line && line->canTranslate(); | ||
534 | } | ||
535 | |||
536 | void LLLineEditor::context_translate(void * data) | ||
537 | { | ||
538 | LLLineEditor* line = (LLLineEditor*)data; | ||
539 | LLMenuGL* menu = line ? (LLMenuGL*)(line->mPopupMenuHandle.get()) : NULL; | ||
540 | LLMenuGL* translate_menu = menu ? menu->getChildMenuByName("Translation Options", TRUE) : NULL; | ||
541 | if (!translate_menu) | ||
542 | { | ||
543 | return; | ||
544 | } | ||
545 | const std::string to_lang = translate_menu->getHighlightedItem()->getName(); | ||
546 | |||
547 | bool has_text = false; | ||
548 | S32 start, length; | ||
549 | if (line->hasSelection()) | ||
550 | { | ||
551 | // translate selection | ||
552 | start = llmin(line->mSelectionStart, line->mSelectionEnd); | ||
553 | length = abs(line->mSelectionEnd - line->mSelectionStart); | ||
554 | has_text = length > 0; | ||
555 | } | ||
556 | else | ||
557 | { | ||
558 | // translate one word at click position | ||
559 | S32 at = line->calculateCursorFromMouse(line->mLastContextMenuX); | ||
560 | has_text = line->getWordBoundriesAt(at, &start, &length); | ||
561 | } | ||
562 | |||
563 | if (has_text) | ||
564 | { | ||
565 | std::string to_translate = wstring_to_utf8str(line->getWText().substr(start, length)); | ||
566 | LLHTTPClient::ResponderPtr result = LineChatTranslationReceiver::build(to_lang, line, start, length); | ||
567 | LLTranslate::translateMessage(result,"", to_lang, to_translate); | ||
568 | } | ||
569 | } | ||
570 | |||
571 | void LLLineEditor::spell_show(void * data) | ||
572 | { | ||
573 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | ||
574 | LLLineEditor* line = tempBind->origin; | ||
575 | |||
576 | if (tempBind && line) | ||
577 | { | ||
578 | BOOL show = (tempBind->word == "Show Misspellings"); | ||
579 | glggHunSpell->setSpellCheckHighlight(show); | ||
580 | } | ||
581 | } | ||
582 | |||
583 | void LLLineEditor::getMisspelledWordsPositions(std::vector<S32>& misspell_positions) | ||
584 | { | ||
585 | misspell_positions.clear(); | ||
586 | const LLWString& text = mText.getWString(); | ||
587 | |||
588 | //llinfos << "end of box is at " << cursorloc << " and end of text is at " << text.length() << llendl; | ||
589 | S32 wordStart=0; | ||
590 | S32 wordEnd=mStartSpellHere; | ||
591 | while(wordEnd < mEndSpellHere) | ||
592 | { | ||
593 | //go through all the chars... XD | ||
594 | if( LLTextEditor::isPartOfWord( text[wordEnd] ) ) | ||
595 | |||
596 | { | ||
597 | // Select word the cursor is over | ||
598 | while ((wordEnd > 0) && LLTextEditor::isPartOfWord(text[wordEnd-1])) | ||
599 | { | ||
600 | wordEnd--; | ||
601 | } | ||
602 | wordStart=wordEnd; | ||
603 | while ((wordEnd < (S32)text.length()) && LLTextEditor::isPartOfWord( text[wordEnd] ) ) | ||
604 | { | ||
605 | wordEnd++; | ||
606 | } | ||
607 | |||
608 | //got a word? -- MC | ||
609 | if (wordStart != wordEnd) | ||
610 | { | ||
611 | std::string selectedWord(std::string(text.begin(), | ||
612 | text.end()).substr(wordStart,wordEnd-wordStart)); | ||
613 | |||
614 | if(!selectedWord.empty() && !glggHunSpell->isSpelledRight(selectedWord)) | ||
615 | { | ||
616 | //misspelled word here, and you have just right clicked on it! | ||
617 | //get the center of this word.. | ||
618 | //S32 center = llround( (wordEnd-wordStart)/2 ) + wordStart; | ||
619 | //turn this cursor position into a pixel pos | ||
620 | //center = findPixelNearestPos(center-getCursor()); | ||
621 | |||
622 | misspell_positions.push_back(wordStart); | ||
623 | misspell_positions.push_back(wordEnd); | ||
624 | } | ||
625 | } | ||
626 | } | ||
627 | wordEnd++; | ||
628 | } | ||
629 | } | ||
630 | |||
631 | void LLLineEditor::spell_add(void* data) | ||
632 | { | ||
633 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | ||
634 | if (tempBind) | ||
635 | { | ||
636 | glggHunSpell->addWordToCustomDictionary(tempBind->word); | ||
637 | tempBind->origin->mPrevSpelledText="";//make it update | ||
638 | } | ||
639 | } | ||
640 | |||
641 | BOOL LLLineEditor::context_enable_paste(void* data) | ||
642 | { | ||
643 | LLLineEditor* line = (LLLineEditor*)data; | ||
644 | return (line && line->canPaste()); | ||
645 | } | ||
646 | |||
647 | void LLLineEditor::context_paste(void* data) | ||
648 | { | ||
649 | LLLineEditor* line = (LLLineEditor*)data; | ||
650 | if(line)line->paste(); | ||
651 | } | ||
652 | |||
653 | BOOL LLLineEditor::context_enable_delete(void* data) | ||
654 | { | ||
655 | LLLineEditor* line = (LLLineEditor*)data; | ||
656 | return (line && line->canDoDelete()); | ||
657 | } | ||
658 | |||
659 | void LLLineEditor::context_delete(void* data) | ||
660 | { | ||
661 | LLLineEditor* line = (LLLineEditor*)data; | ||
662 | if(line)line->doDelete(); | ||
663 | } | ||
664 | |||
665 | BOOL LLLineEditor::context_enable_selectall(void* data) | ||
666 | { | ||
667 | LLLineEditor* line = (LLLineEditor*)data; | ||
668 | return (line && line->canSelectAll()); | ||
669 | } | ||
670 | |||
671 | void LLLineEditor::context_selectall(void* data) | ||
672 | { | ||
673 | LLLineEditor* line = (LLLineEditor*)data; | ||
674 | if(line)line->selectAll(); | ||
675 | } | ||
420 | 676 | ||
421 | void LLLineEditor::startSelection() | 677 | void LLLineEditor::startSelection() |
422 | { | 678 | { |
@@ -508,6 +764,105 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
508 | return TRUE; | 764 | return TRUE; |
509 | } | 765 | } |
510 | 766 | ||
767 | |||
768 | BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | ||
769 | { | ||
770 | setFocus(TRUE); | ||
771 | |||
772 | //setCursorAtLocalPos( x); | ||
773 | S32 wordStart = 0; | ||
774 | S32 wordLen = 0; | ||
775 | S32 pos = calculateCursorFromMouse(x); | ||
776 | |||
777 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | ||
778 | if (menu) | ||
779 | { | ||
780 | if(menu->isOpen()) | ||
781 | { | ||
782 | menu->setVisible(FALSE); | ||
783 | } | ||
784 | for (int i = 0;i<(int)suggestionMenuItems.size();i++) | ||
785 | { | ||
786 | SpellMenuBind * tempBind = suggestionMenuItems[i]; | ||
787 | if (tempBind) | ||
788 | { | ||
789 | menu->remove((LLMenuItemCallGL *)tempBind->menuItem); | ||
790 | ((LLMenuItemCallGL *)tempBind->menuItem)->die(); | ||
791 | //delete tempBind->menuItem; | ||
792 | //tempBind->menuItem = NULL; | ||
793 | delete tempBind; | ||
794 | } | ||
795 | } | ||
796 | suggestionMenuItems.clear(); | ||
797 | |||
798 | // spell_check="true" in xui | ||
799 | menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable); | ||
800 | if (!mReadOnly && mSpellCheckable) | ||
801 | { | ||
802 | // search for word matches | ||
803 | bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen); | ||
804 | if (is_word_part) | ||
805 | { | ||
806 | const LLWString& text = mText.getWString(); | ||
807 | std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen)); | ||
808 | |||
809 | if (!glggHunSpell->isSpelledRight(selectedWord)) | ||
810 | { | ||
811 | //misspelled word here, and you have just right clicked on it! | ||
812 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); | ||
813 | |||
814 | for (int i = 0; i<(int)suggs.size() ;i++) | ||
815 | { | ||
816 | SpellMenuBind * tempStruct = new SpellMenuBind; | ||
817 | tempStruct->origin = this; | ||
818 | tempStruct->word = suggs[i]; | ||
819 | tempStruct->wordPositionEnd = wordStart + wordLen; | ||
820 | tempStruct->wordPositionStart=wordStart; | ||
821 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | ||
822 | tempStruct->word, spell_correct, NULL, tempStruct); | ||
823 | //new LLMenuItemCallGL("Select All", context_selectall, NULL, this)); | ||
824 | tempStruct->menuItem = suggMenuItem; | ||
825 | suggestionMenuItems.push_back(tempStruct); | ||
826 | menu->append(suggMenuItem); | ||
827 | } | ||
828 | SpellMenuBind * tempStruct = new SpellMenuBind; | ||
829 | tempStruct->origin = this; | ||
830 | tempStruct->word = selectedWord; | ||
831 | tempStruct->wordPositionEnd = wordStart + wordLen; | ||
832 | tempStruct->wordPositionStart=wordStart; | ||
833 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | ||
834 | "Add Word", spell_add, NULL, tempStruct); | ||
835 | tempStruct->menuItem = suggMenuItem; | ||
836 | suggestionMenuItems.push_back(tempStruct); | ||
837 | menu->append(suggMenuItem); | ||
838 | } | ||
839 | } | ||
840 | |||
841 | SpellMenuBind * tempStruct = new SpellMenuBind; | ||
842 | tempStruct->origin = this; | ||
843 | if (glggHunSpell->getSpellCheckHighlight()) | ||
844 | { | ||
845 | tempStruct->word = "Hide Misspellings"; | ||
846 | } | ||
847 | else | ||
848 | { | ||
849 | tempStruct->word = "Show Misspellings"; | ||
850 | } | ||
851 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | ||
852 | tempStruct->word, spell_show, NULL, tempStruct); | ||
853 | tempStruct->menuItem = suggMenuItem; | ||
854 | suggestionMenuItems.push_back(tempStruct); | ||
855 | menu->append(suggMenuItem); | ||
856 | } | ||
857 | |||
858 | mLastContextMenuX = x; | ||
859 | menu->buildDrawLabels(); | ||
860 | menu->updateParent(LLMenuGL::sMenuContainer); | ||
861 | LLMenuGL::showPopup(this, menu, x, y); | ||
862 | } | ||
863 | return TRUE; | ||
864 | } | ||
865 | |||
511 | BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) | 866 | BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask) |
512 | { | 867 | { |
513 | // Check first whether the "clear search" button wants to deal with this. | 868 | // Check first whether the "clear search" button wants to deal with this. |
@@ -662,6 +1017,11 @@ BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask) | |||
662 | 1017 | ||
663 | return handled; | 1018 | return handled; |
664 | } | 1019 | } |
1020 | BOOL LLLineEditor::handleHScrollWheel(S32 x, S32 y, S32 clicks) | ||
1021 | { | ||
1022 | mScrollHPos = llclamp(mScrollHPos + clicks * 3, 0, mText.length()); | ||
1023 | return TRUE; | ||
1024 | } | ||
665 | 1025 | ||
666 | 1026 | ||
667 | BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask) | 1027 | BOOL LLLineEditor::handleMouseUp(S32 x, S32 y, MASK mask) |
@@ -774,13 +1134,9 @@ void LLLineEditor::setSelection(S32 start, S32 end) | |||
774 | { | 1134 | { |
775 | S32 len = mText.length(); | 1135 | S32 len = mText.length(); |
776 | 1136 | ||
777 | mIsSelecting = TRUE; | 1137 | mSelectionStart = llclamp(start, 0, len); |
778 | 1138 | mSelectionEnd = llclamp(end, 0, len); | |
779 | // JC, yes, this seems odd, but I think you have to presume a | 1139 | setCursor(end); |
780 | // selection dragged from the end towards the start. | ||
781 | mSelectionStart = llclamp(end, 0, len); | ||
782 | mSelectionEnd = llclamp(start, 0, len); | ||
783 | setCursor(start); | ||
784 | } | 1140 | } |
785 | 1141 | ||
786 | void LLLineEditor::setDrawAsterixes(BOOL b) | 1142 | void LLLineEditor::setDrawAsterixes(BOOL b) |
@@ -817,6 +1173,26 @@ S32 LLLineEditor::nextWordPos(S32 cursorPos) const | |||
817 | return cursorPos; | 1173 | return cursorPos; |
818 | } | 1174 | } |
819 | 1175 | ||
1176 | BOOL LLLineEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const | ||
1177 | { | ||
1178 | const LLWString& wtext = mText.getWString(); | ||
1179 | S32 pos = at; | ||
1180 | if (LLTextEditor::isPartOfWord(wtext[pos])) | ||
1181 | { | ||
1182 | while ( (pos > 0) && LLTextEditor::isPartOfWord(wtext[pos - 1]) ) | ||
1183 | { | ||
1184 | pos--; | ||
1185 | } | ||
1186 | *word_begin = pos; | ||
1187 | while ( (pos < (S32)wtext.length()) && LLTextEditor::isPartOfWord(wtext[pos]) ) | ||
1188 | { | ||
1189 | pos++; | ||
1190 | } | ||
1191 | *word_length = pos - *word_begin; | ||
1192 | return TRUE; | ||
1193 | } | ||
1194 | return FALSE; | ||
1195 | } | ||
820 | 1196 | ||
821 | BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) | 1197 | BOOL LLLineEditor::handleSelectionKey(KEY key, MASK mask) |
822 | { | 1198 | { |
@@ -912,7 +1288,7 @@ void LLLineEditor::deleteSelection() | |||
912 | if( !mReadOnly && hasSelection() ) | 1288 | if( !mReadOnly && hasSelection() ) |
913 | { | 1289 | { |
914 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); | 1290 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); |
915 | S32 selection_length = abs( mSelectionStart - mSelectionEnd ); | 1291 | S32 selection_length = llabs( mSelectionStart - mSelectionEnd ); |
916 | 1292 | ||
917 | mText.erase(left_pos, selection_length); | 1293 | mText.erase(left_pos, selection_length); |
918 | deselect(); | 1294 | deselect(); |
@@ -925,6 +1301,67 @@ BOOL LLLineEditor::canCut() const | |||
925 | return !mReadOnly && !mDrawAsterixes && hasSelection(); | 1301 | return !mReadOnly && !mDrawAsterixes && hasSelection(); |
926 | } | 1302 | } |
927 | 1303 | ||
1304 | // method to define the associated callbacks | ||
1305 | void LLLineEditor::defineMenuCallbacks(LLMenuGL* menu) { | ||
1306 | |||
1307 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
1308 | "Cut Text", | ||
1309 | this, | ||
1310 | (void*)context_enable_cut); | ||
1311 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
1312 | "Cut Text", | ||
1313 | this, | ||
1314 | (void*)context_cut); | ||
1315 | |||
1316 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
1317 | "Copy Text", | ||
1318 | this, | ||
1319 | (void*)context_enable_copy); | ||
1320 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
1321 | "Copy Text", | ||
1322 | this, | ||
1323 | (void*)context_copy); | ||
1324 | |||
1325 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
1326 | "Paste Text", | ||
1327 | this, | ||
1328 | (void*)context_enable_paste); | ||
1329 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
1330 | "Paste Text", | ||
1331 | this, | ||
1332 | (void*)context_paste); | ||
1333 | |||
1334 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
1335 | "Delete Text", | ||
1336 | this, | ||
1337 | (void*)context_enable_delete); | ||
1338 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
1339 | "Delete Text", | ||
1340 | this, | ||
1341 | (void*)context_delete); | ||
1342 | |||
1343 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
1344 | "Select All Text", | ||
1345 | this, | ||
1346 | (void*)context_enable_selectall); | ||
1347 | menu->setCtrlResponse(1+LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
1348 | "Select All Text", | ||
1349 | this, | ||
1350 | (void*)context_selectall); | ||
1351 | |||
1352 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
1353 | "Translate Text", | ||
1354 | this, | ||
1355 | (void*)context_enable_translate); | ||
1356 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_TRANSLATE, | ||
1357 | "Translate Text", | ||
1358 | this, | ||
1359 | (void*)context_translate); | ||
1360 | |||
1361 | |||
1362 | |||
1363 | } | ||
1364 | |||
928 | // cut selection to clipboard | 1365 | // cut selection to clipboard |
929 | void LLLineEditor::cut() | 1366 | void LLLineEditor::cut() |
930 | { | 1367 | { |
@@ -935,7 +1372,7 @@ void LLLineEditor::cut() | |||
935 | 1372 | ||
936 | 1373 | ||
937 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); | 1374 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); |
938 | S32 length = abs( mSelectionStart - mSelectionEnd ); | 1375 | S32 length = llabs( mSelectionStart - mSelectionEnd ); |
939 | gClipboard.copyFromSubstring( mText.getWString(), left_pos, length ); | 1376 | gClipboard.copyFromSubstring( mText.getWString(), left_pos, length ); |
940 | deleteSelection(); | 1377 | deleteSelection(); |
941 | 1378 | ||
@@ -966,11 +1403,69 @@ void LLLineEditor::copy() | |||
966 | if( canCopy() ) | 1403 | if( canCopy() ) |
967 | { | 1404 | { |
968 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); | 1405 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); |
969 | S32 length = abs( mSelectionStart - mSelectionEnd ); | 1406 | S32 length = llabs( mSelectionStart - mSelectionEnd ); |
970 | gClipboard.copyFromSubstring( mText.getWString(), left_pos, length ); | 1407 | gClipboard.copyFromSubstring( mText.getWString(), left_pos, length ); |
971 | } | 1408 | } |
972 | } | 1409 | } |
973 | 1410 | ||
1411 | void LLLineEditor::spellReplace(SpellMenuBind* spellData) | ||
1412 | { | ||
1413 | mText.erase(spellData->wordPositionStart, | ||
1414 | spellData->wordPositionEnd - spellData->wordPositionStart); | ||
1415 | insert(spellData->word,spellData->wordPositionStart); | ||
1416 | mCursorPos+=spellData->word.length() - (spellData->wordPositionEnd-spellData->wordPositionStart); | ||
1417 | |||
1418 | |||
1419 | } | ||
1420 | |||
1421 | void LLLineEditor::translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length) | ||
1422 | { | ||
1423 | //*TODO: should probably check if the content was modified since the http query | ||
1424 | // was made, so we don't insert text in the wrong place. | ||
1425 | BOOL replace = gSavedSettings.getBOOL("EmeraldTranslateReplace"); | ||
1426 | std::string text = replace ? translation : " (" + translation + ")"; | ||
1427 | S32 pos = replace ? orig_start : orig_start + orig_length; | ||
1428 | if (replace) | ||
1429 | { | ||
1430 | mText.erase(orig_start, orig_length); | ||
1431 | } | ||
1432 | insert(text, pos); | ||
1433 | |||
1434 | S32 text_wlen = utf8str_to_wstring(text).length(); | ||
1435 | if (hasSelection()) | ||
1436 | { | ||
1437 | setSelection(pos, pos + text_wlen); | ||
1438 | } | ||
1439 | setCursor(pos + text_wlen); | ||
1440 | } | ||
1441 | |||
1442 | BOOL LLLineEditor::canTranslate() const | ||
1443 | { | ||
1444 | // if allow_translate="true" in xui, and if other factors permit, we allow it | ||
1445 | S32 pos = calculateCursorFromMouse(mLastContextMenuX); | ||
1446 | const LLWString& wtext = getWText(); | ||
1447 | bool is_word_part = (pos > -1) && LLTextEditor::isPartOfWord(wtext[pos]); | ||
1448 | return (mAllowTranslate && !mReadOnly && (is_word_part || hasSelection())); | ||
1449 | } | ||
1450 | |||
1451 | void LLLineEditor::insert(std::string what, S32 wher) | ||
1452 | { | ||
1453 | LLLineEditorRollback rollback(this); | ||
1454 | LLWString clean_string(utf8str_to_wstring(what)); | ||
1455 | LLWStringUtil::replaceTabsWithSpaces(clean_string, 4); | ||
1456 | mText.insert(wher, clean_string); | ||
1457 | //see if we should move over the cursor acordingly | ||
1458 | // Validate new string and rollback the if needed. | ||
1459 | BOOL need_to_rollback = ( mPrevalidateFunc && !mPrevalidateFunc( mText.getWString() ) ); | ||
1460 | if( need_to_rollback ) | ||
1461 | { | ||
1462 | rollback.doRollback( this ); | ||
1463 | reportBadKeystroke(); | ||
1464 | } | ||
1465 | else if( mKeystrokeCallback ) | ||
1466 | mKeystrokeCallback( this, mCallbackUserData ); | ||
1467 | } | ||
1468 | |||
974 | BOOL LLLineEditor::canPaste() const | 1469 | BOOL LLLineEditor::canPaste() const |
975 | { | 1470 | { |
976 | return !mReadOnly && gClipboard.canPasteString(); | 1471 | return !mReadOnly && gClipboard.canPasteString(); |
@@ -993,17 +1488,25 @@ void LLLineEditor::pasteHelper(bool is_primary) | |||
993 | { | 1488 | { |
994 | bool can_paste_it; | 1489 | bool can_paste_it; |
995 | if (is_primary) | 1490 | if (is_primary) |
1491 | { | ||
996 | can_paste_it = canPastePrimary(); | 1492 | can_paste_it = canPastePrimary(); |
1493 | } | ||
997 | else | 1494 | else |
1495 | { | ||
998 | can_paste_it = canPaste(); | 1496 | can_paste_it = canPaste(); |
1497 | } | ||
999 | 1498 | ||
1000 | if (can_paste_it) | 1499 | if (can_paste_it) |
1001 | { | 1500 | { |
1002 | LLWString paste; | 1501 | LLWString paste; |
1003 | if (is_primary) | 1502 | if (is_primary) |
1503 | { | ||
1004 | paste = gClipboard.getPastePrimaryWString(); | 1504 | paste = gClipboard.getPastePrimaryWString(); |
1505 | } | ||
1005 | else | 1506 | else |
1507 | { | ||
1006 | paste = gClipboard.getPasteWString(); | 1508 | paste = gClipboard.getPasteWString(); |
1509 | } | ||
1007 | 1510 | ||
1008 | if (!paste.empty()) | 1511 | if (!paste.empty()) |
1009 | { | 1512 | { |
@@ -1018,7 +1521,7 @@ void LLLineEditor::pasteHelper(bool is_primary) | |||
1018 | 1521 | ||
1019 | // Clean up string (replace tabs and returns and remove characters that our fonts don't support.) | 1522 | // Clean up string (replace tabs and returns and remove characters that our fonts don't support.) |
1020 | LLWString clean_string(paste); | 1523 | LLWString clean_string(paste); |
1021 | LLWStringUtil::replaceTabsWithSpaces(clean_string, 1); | 1524 | LLWStringUtil::replaceTabsWithSpaces(clean_string, 4); |
1022 | //clean_string = wstring_detabify(paste, 1); | 1525 | //clean_string = wstring_detabify(paste, 1); |
1023 | LLWStringUtil::replaceChar(clean_string, '\n', mReplaceNewlinesWithSpaces ? ' ' : 182); // 182 == paragraph character | 1526 | LLWStringUtil::replaceChar(clean_string, '\n', mReplaceNewlinesWithSpaces ? ' ' : 182); // 182 == paragraph character |
1024 | 1527 | ||
@@ -1074,7 +1577,7 @@ void LLLineEditor::copyPrimary() | |||
1074 | if( canCopy() ) | 1577 | if( canCopy() ) |
1075 | { | 1578 | { |
1076 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); | 1579 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); |
1077 | S32 length = abs( mSelectionStart - mSelectionEnd ); | 1580 | S32 length = llabs( mSelectionStart - mSelectionEnd ); |
1078 | gClipboard.copyFromPrimarySubstring( mText.getWString(), left_pos, length ); | 1581 | gClipboard.copyFromPrimarySubstring( mText.getWString(), left_pos, length ); |
1079 | } | 1582 | } |
1080 | } | 1583 | } |
@@ -1322,6 +1825,14 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask ) | |||
1322 | BOOL handled = FALSE; | 1825 | BOOL handled = FALSE; |
1323 | BOOL selection_modified = FALSE; | 1826 | BOOL selection_modified = FALSE; |
1324 | 1827 | ||
1828 | // SL-51858: Key presses are not being passed to the Popup menu. | ||
1829 | // A proper fix is non-trivial so instead just close the menu. | ||
1830 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | ||
1831 | if (menu && menu->isOpen()) | ||
1832 | { | ||
1833 | LLMenuGL::sMenuContainer->hideMenus(); | ||
1834 | } | ||
1835 | |||
1325 | if ( gFocusMgr.getKeyboardFocus() == this ) | 1836 | if ( gFocusMgr.getKeyboardFocus() == this ) |
1326 | { | 1837 | { |
1327 | LLLineEditorRollback rollback( this ); | 1838 | LLLineEditorRollback rollback( this ); |
@@ -1396,6 +1907,13 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char) | |||
1396 | 1907 | ||
1397 | if ( (gFocusMgr.getKeyboardFocus() == this) && getVisible() && !mReadOnly) | 1908 | if ( (gFocusMgr.getKeyboardFocus() == this) && getVisible() && !mReadOnly) |
1398 | { | 1909 | { |
1910 | // SL-51858: Key presses are not being passed to the Popup menu. | ||
1911 | // A proper fix is non-trivial so instead just close the menu. | ||
1912 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | ||
1913 | if (menu && menu->isOpen()) | ||
1914 | { | ||
1915 | LLMenuGL::sMenuContainer->hideMenus(); | ||
1916 | } | ||
1399 | handled = TRUE; | 1917 | handled = TRUE; |
1400 | 1918 | ||
1401 | LLLineEditorRollback rollback( this ); | 1919 | LLLineEditorRollback rollback( this ); |
@@ -1472,9 +1990,106 @@ void LLLineEditor::doDelete() | |||
1472 | } | 1990 | } |
1473 | } | 1991 | } |
1474 | 1992 | ||
1993 | void LLLineEditor::autoCorrectText() | ||
1994 | { | ||
1995 | static BOOL *doAnything = rebind_llcontrol<BOOL>("EmeraldEnableAutoCorrect", &gSavedSettings, true); | ||
1996 | if (!mReadOnly && *doAnything && isSpellDirty()) | ||
1997 | { | ||
1998 | S32 wordStart = 0; | ||
1999 | S32 wordEnd = mCursorPos-1; | ||
2000 | //llinfos <<"Checking Word, Cursor is at "<<mCursorPos<<" and text is "<<mText.getString().c_str()<<llendl; | ||
2001 | if (wordEnd < 1) | ||
2002 | { | ||
2003 | return; | ||
2004 | } | ||
2005 | const LLWString& text = mText.getWString(); | ||
2006 | if (text.size() < 1 || LLTextEditor::isPartOfWord(text[wordEnd])) | ||
2007 | { | ||
2008 | return;//we only check on word breaks | ||
2009 | } | ||
2010 | |||
2011 | wordEnd--; | ||
2012 | if (LLTextEditor::isPartOfWord(text[wordEnd])) | ||
2013 | { | ||
2014 | while ((wordEnd > 0) && (' '!=text[wordEnd-1])) | ||
2015 | { | ||
2016 | wordEnd--; | ||
2017 | } | ||
2018 | wordStart = wordEnd; | ||
2019 | while ((wordEnd < (S32)text.length()) && (' '!=text[wordEnd] ) ) | ||
2020 | { | ||
2021 | wordEnd++; | ||
2022 | } | ||
2023 | std::string lastTypedWord(std::string(text.begin(), | ||
2024 | text.end()).substr(wordStart, wordEnd-wordStart)); | ||
2025 | //llinfos << " The last typed word has been chosen, it is "<<lastTypedWord.c_str()<<llendl; | ||
2026 | |||
2027 | std::string correctedWord(LGGAutoCorrect::getInstance()->replaceWord(lastTypedWord)); | ||
2028 | if(correctedWord != lastTypedWord) | ||
2029 | { | ||
2030 | int dif = correctedWord.length()-lastTypedWord.length(); | ||
2031 | std::string regText(mText); | ||
2032 | //int wordStart = regText.find(lastTypedWord); | ||
2033 | regText.replace(wordStart,lastTypedWord.length(),correctedWord); | ||
2034 | mText=regText; | ||
2035 | mCursorPos+=dif; | ||
2036 | } | ||
2037 | } | ||
2038 | } | ||
2039 | } | ||
2040 | |||
2041 | void LLLineEditor::drawMisspelled(const LLRect& background) | ||
2042 | { | ||
2043 | if (!mReadOnly && mSpellCheckable) | ||
2044 | { | ||
2045 | S32 newStartSpellHere = mScrollHPos; | ||
2046 | S32 cursorloc = calculateCursorFromMouse(mMaxHPixels); | ||
2047 | S32 newStopSpellHere = (((S32)mText.length())>cursorloc) ? cursorloc : (S32)mText.length(); | ||
2048 | |||
2049 | F32 elapsed = mSpellTimer.getElapsedTimeF32(); | ||
2050 | if (S32(elapsed / 1) & 1) | ||
2051 | { | ||
2052 | if (isSpellDirty() || (newStartSpellHere != mStartSpellHere) || ( newStopSpellHere != mEndSpellHere)) | ||
2053 | { | ||
2054 | mStartSpellHere = newStartSpellHere; | ||
2055 | mEndSpellHere = newStopSpellHere; | ||
2056 | resetSpellDirty(); | ||
2057 | getMisspelledWordsPositions(mMisspellLocations); | ||
2058 | } | ||
2059 | } | ||
2060 | |||
2061 | if (!mMisspellLocations.empty() && glggHunSpell->getSpellCheckHighlight()) | ||
2062 | { | ||
2063 | for (int i =0; i<(int)mMisspellLocations.size(); i++) | ||
2064 | { | ||
2065 | S32 wstart =findPixelNearestPos( mMisspellLocations[i]-getCursor()); | ||
2066 | S32 wend = findPixelNearestPos(mMisspellLocations[++i]-getCursor()); | ||
2067 | S32 maxw = getRect().getWidth(); | ||
2068 | |||
2069 | if (wend > maxw) | ||
2070 | { | ||
2071 | wend = maxw; | ||
2072 | } | ||
2073 | if (wstart > maxw) | ||
2074 | { | ||
2075 | wstart = maxw; | ||
2076 | } | ||
2077 | gGL.color4ub(255,0,0,200); | ||
2078 | //3 line zig zags.. | ||
2079 | while (wstart < wend) | ||
2080 | { | ||
2081 | gl_line_2d(wstart, background.mBottom-1, wstart+3, background.mBottom+2); | ||
2082 | gl_line_2d(wstart+3, background.mBottom+2, wstart+6, background.mBottom-1); | ||
2083 | wstart+=6; | ||
2084 | } | ||
2085 | } | ||
2086 | } | ||
2087 | } | ||
2088 | } | ||
1475 | 2089 | ||
1476 | void LLLineEditor::draw() | 2090 | void LLLineEditor::draw() |
1477 | { | 2091 | { |
2092 | autoCorrectText(); | ||
1478 | S32 text_len = mText.length(); | 2093 | S32 text_len = mText.length(); |
1479 | 2094 | ||
1480 | std::string saved_text; | 2095 | std::string saved_text; |
@@ -1661,6 +2276,9 @@ void LLLineEditor::draw() | |||
1661 | mBorder->setVisible(FALSE); // no more programmatic art. | 2276 | mBorder->setVisible(FALSE); // no more programmatic art. |
1662 | #endif | 2277 | #endif |
1663 | 2278 | ||
2279 | drawMisspelled(background); | ||
2280 | resetSpellDirty(); | ||
2281 | |||
1664 | // If we're editing... | 2282 | // If we're editing... |
1665 | if( gFocusMgr.getKeyboardFocus() == this) | 2283 | if( gFocusMgr.getKeyboardFocus() == this) |
1666 | { | 2284 | { |
@@ -2122,7 +2740,6 @@ BOOL LLLineEditor::prevalidatePrintableNotPipe(const LLWString &str) | |||
2122 | return rv; | 2740 | return rv; |
2123 | } | 2741 | } |
2124 | 2742 | ||
2125 | |||
2126 | // static | 2743 | // static |
2127 | BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str) | 2744 | BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str) |
2128 | { | 2745 | { |
@@ -2147,6 +2764,25 @@ BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str) | |||
2147 | } | 2764 | } |
2148 | 2765 | ||
2149 | // static | 2766 | // static |
2767 | BOOL LLLineEditor::prevalidatePrintableSpace(const LLWString &str) | ||
2768 | { | ||
2769 | BOOL rv = TRUE; | ||
2770 | S32 len = str.length(); | ||
2771 | if(len == 0) return rv; | ||
2772 | while(len--) | ||
2773 | { | ||
2774 | if( !(LLStringOps::isAlnum((char)str[len]) || | ||
2775 | LLStringOps::isPunct((char)str[len]) || | ||
2776 | ' ' == str[len]) ) | ||
2777 | { | ||
2778 | rv = FALSE; | ||
2779 | break; | ||
2780 | } | ||
2781 | } | ||
2782 | return rv; | ||
2783 | } | ||
2784 | |||
2785 | // static | ||
2150 | BOOL LLLineEditor::prevalidateASCII(const LLWString &str) | 2786 | BOOL LLLineEditor::prevalidateASCII(const LLWString &str) |
2151 | { | 2787 | { |
2152 | BOOL rv = TRUE; | 2788 | BOOL rv = TRUE; |
@@ -2166,6 +2802,7 @@ BOOL LLLineEditor::evaluateFloat() | |||
2166 | { | 2802 | { |
2167 | bool success = false; | 2803 | bool success = false; |
2168 | std::string expr = getText(); | 2804 | std::string expr = getText(); |
2805 | LLStringUtil::toUpper(expr); | ||
2169 | 2806 | ||
2170 | // user deleted the contents, nothing to evaluate -- MC | 2807 | // user deleted the contents, nothing to evaluate -- MC |
2171 | if (expr.empty()) | 2808 | if (expr.empty()) |
@@ -2339,6 +2976,16 @@ LLView* LLLineEditor::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory | |||
2339 | { | 2976 | { |
2340 | line_editor->setCommitOnFocusLost(commit_on_focus_lost); | 2977 | line_editor->setCommitOnFocusLost(commit_on_focus_lost); |
2341 | } | 2978 | } |
2979 | BOOL spell_checking = FALSE; | ||
2980 | if (node->getAttributeBOOL("spell_check", spell_checking)) | ||
2981 | { | ||
2982 | line_editor->setSpellCheckable(spell_checking); | ||
2983 | } | ||
2984 | BOOL allow_translate = TRUE; | ||
2985 | if (node->getAttributeBOOL("allow_translate", allow_translate)) | ||
2986 | { | ||
2987 | line_editor->setAllowTranslate(allow_translate); | ||
2988 | } | ||
2342 | 2989 | ||
2343 | line_editor->setColorParameters(node); | 2990 | line_editor->setColorParameters(node); |
2344 | 2991 | ||
diff --git a/linden/indra/llui/lllineeditor.h b/linden/indra/llui/lllineeditor.h index fc1b75f..b3e21ce 100644 --- a/linden/indra/llui/lllineeditor.h +++ b/linden/indra/llui/lllineeditor.h | |||
@@ -55,6 +55,7 @@ | |||
55 | class LLFontGL; | 55 | class LLFontGL; |
56 | class LLLineEditorRollback; | 56 | class LLLineEditorRollback; |
57 | class LLButton; | 57 | class LLButton; |
58 | class LLMenuGL; | ||
58 | 59 | ||
59 | typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr); | 60 | typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr); |
60 | 61 | ||
@@ -78,6 +79,7 @@ public: | |||
78 | LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE, | 79 | LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE, |
79 | S32 border_thickness = 1); | 80 | S32 border_thickness = 1); |
80 | 81 | ||
82 | |||
81 | virtual ~LLLineEditor(); | 83 | virtual ~LLLineEditor(); |
82 | 84 | ||
83 | virtual LLXMLNodePtr getXML(bool save_children = true) const; | 85 | virtual LLXMLNodePtr getXML(bool save_children = true) const; |
@@ -89,17 +91,36 @@ public: | |||
89 | /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); | 91 | /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); |
90 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); | 92 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); |
91 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); | 93 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); |
94 | /*virtual*/ BOOL handleHScrollWheel(S32 x, S32 y, S32 clicks); | ||
92 | /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask); | 95 | /*virtual*/ BOOL handleDoubleClick(S32 x,S32 y,MASK mask); |
93 | /*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); | 96 | /*virtual*/ BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); |
97 | /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); | ||
94 | /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); | 98 | /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); |
95 | /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); | 99 | /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); |
96 | /*virtual*/ void onMouseCaptureLost(); | 100 | /*virtual*/ void onMouseCaptureLost(); |
97 | 101 | ||
98 | // LLEditMenuHandler overrides | 102 | struct SpellMenuBind |
103 | { | ||
104 | LLLineEditor* origin; | ||
105 | void * menuItem; | ||
106 | std::string word; | ||
107 | S32 wordPositionStart; | ||
108 | S32 wordPositionEnd; | ||
109 | }; | ||
110 | |||
111 | virtual void spellReplace(SpellMenuBind* spellData); | ||
112 | virtual void translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length); | ||
113 | virtual BOOL canTranslate() const; | ||
114 | virtual void insert(std::string what,S32 wher); | ||
115 | |||
116 | // LLEditMenuHandler overrides and menu set up methods. | ||
117 | void defineMenuCallbacks(LLMenuGL* menu); | ||
99 | virtual void cut(); | 118 | virtual void cut(); |
100 | virtual BOOL canCut() const; | 119 | virtual BOOL canCut() const; |
120 | |||
101 | virtual void copy(); | 121 | virtual void copy(); |
102 | virtual BOOL canCopy() const; | 122 | virtual BOOL canCopy() const; |
123 | |||
103 | virtual void paste(); | 124 | virtual void paste(); |
104 | virtual BOOL canPaste() const; | 125 | virtual BOOL canPaste() const; |
105 | 126 | ||
@@ -117,8 +138,28 @@ public: | |||
117 | virtual void deselect(); | 138 | virtual void deselect(); |
118 | virtual BOOL canDeselect() const; | 139 | virtual BOOL canDeselect() const; |
119 | 140 | ||
141 | static BOOL context_enable_cut(void* data); | ||
142 | static void context_cut(void* data); | ||
143 | static BOOL context_enable_copy(void* data); | ||
144 | static void context_copy(void* data); | ||
145 | static BOOL context_enable_paste(void* data); | ||
146 | static void context_paste(void* data); | ||
147 | static BOOL context_enable_delete(void* data); | ||
148 | static void context_delete(void* data); | ||
149 | static BOOL context_enable_selectall(void* data); | ||
150 | static void context_selectall(void* data); | ||
151 | static BOOL context_enable_translate(void * data); | ||
152 | static void context_translate(void * data); | ||
153 | static void spell_correct(void* data); | ||
154 | static void spell_show(void* data); | ||
155 | static void spell_add(void* data); | ||
156 | |||
157 | void getMisspelledWordsPositions(std::vector<S32>& misspell_positions); | ||
158 | |||
120 | // view overrides | 159 | // view overrides |
121 | virtual void draw(); | 160 | virtual void draw(); |
161 | void autoCorrectText(); | ||
162 | void drawMisspelled(const LLRect& background); | ||
122 | virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE); | 163 | virtual void reshape(S32 width,S32 height,BOOL called_from_parent=TRUE); |
123 | virtual void onFocusReceived(); | 164 | virtual void onFocusReceived(); |
124 | virtual void onFocusLost(); | 165 | virtual void onFocusLost(); |
@@ -133,6 +174,8 @@ public: | |||
133 | virtual void onCommit(); | 174 | virtual void onCommit(); |
134 | virtual BOOL isDirty() const { return mText.getString() != mPrevText; } // Returns TRUE if user changed value at all | 175 | virtual BOOL isDirty() const { return mText.getString() != mPrevText; } // Returns TRUE if user changed value at all |
135 | virtual void resetDirty() { mPrevText = mText.getString(); } // Clear dirty state | 176 | virtual void resetDirty() { mPrevText = mText.getString(); } // Clear dirty state |
177 | virtual BOOL isSpellDirty() const { return mText.getString() != mPrevSpelledText; } // Returns TRUE if user changed value at all | ||
178 | virtual void resetSpellDirty() { mPrevSpelledText = mText.getString(); } // Clear dirty state | ||
136 | 179 | ||
137 | // assumes UTF8 text | 180 | // assumes UTF8 text |
138 | virtual void setValue(const LLSD& value ) { setText(value.asString()); } | 181 | virtual void setValue(const LLSD& value ) { setText(value.asString()); } |
@@ -168,6 +211,8 @@ public: | |||
168 | void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } | 211 | void setWriteableBgColor( const LLColor4& c ) { mWriteableBgColor = c; } |
169 | void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } | 212 | void setReadOnlyBgColor( const LLColor4& c ) { mReadOnlyBgColor = c; } |
170 | void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; } | 213 | void setFocusBgColor(const LLColor4& c) { mFocusBgColor = c; } |
214 | void setSpellCheckable(BOOL b) { mSpellCheckable = b; } | ||
215 | void setAllowTranslate(BOOL b) { mAllowTranslate = b; } | ||
171 | 216 | ||
172 | const LLColor4& getFgColor() const { return mFgColor; } | 217 | const LLColor4& getFgColor() const { return mFgColor; } |
173 | const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor; } | 218 | const LLColor4& getReadOnlyFgColor() const { return mReadOnlyFgColor; } |
@@ -184,6 +229,7 @@ public: | |||
184 | // get the cursor position of the beginning/end of the prev/next word in the text | 229 | // get the cursor position of the beginning/end of the prev/next word in the text |
185 | S32 prevWordPos(S32 cursorPos) const; | 230 | S32 prevWordPos(S32 cursorPos) const; |
186 | S32 nextWordPos(S32 cursorPos) const; | 231 | S32 nextWordPos(S32 cursorPos) const; |
232 | BOOL getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const; | ||
187 | 233 | ||
188 | BOOL hasSelection() const { return (mSelectionStart != mSelectionEnd); } | 234 | BOOL hasSelection() const { return (mSelectionStart != mSelectionEnd); } |
189 | void startSelection(); | 235 | void startSelection(); |
@@ -210,10 +256,11 @@ public: | |||
210 | static BOOL prevalidateAlphaNumSpace(const LLWString &str ); | 256 | static BOOL prevalidateAlphaNumSpace(const LLWString &str ); |
211 | static BOOL prevalidatePrintableNotPipe(const LLWString &str); | 257 | static BOOL prevalidatePrintableNotPipe(const LLWString &str); |
212 | static BOOL prevalidatePrintableNoSpace(const LLWString &str); | 258 | static BOOL prevalidatePrintableNoSpace(const LLWString &str); |
259 | static BOOL prevalidatePrintableSpace(const LLWString &str); | ||
213 | static BOOL prevalidateASCII(const LLWString &str); | 260 | static BOOL prevalidateASCII(const LLWString &str); |
214 | 261 | ||
215 | static BOOL postvalidateFloat(const std::string &str); | 262 | static BOOL postvalidateFloat(const std::string &str); |
216 | 263 | ||
217 | BOOL evaluateFloat(); | 264 | BOOL evaluateFloat(); |
218 | 265 | ||
219 | // line history support: | 266 | // line history support: |
@@ -225,11 +272,12 @@ public: | |||
225 | private: | 272 | private: |
226 | // private helper methods | 273 | // private helper methods |
227 | 274 | ||
228 | void pasteHelper(bool is_primary); | 275 | void pasteHelper(bool is_primary); |
229 | 276 | ||
230 | void removeChar(); | 277 | void removeChar(); |
231 | void addChar(const llwchar c); | 278 | void addChar(const llwchar c); |
232 | void setCursorAtLocalPos(S32 local_mouse_x); | 279 | void setCursorAtLocalPos(S32 local_mouse_x); |
280 | S32 calculateCursorFromMouse(S32 local_mouse_x) const; | ||
233 | S32 findPixelNearestPos(S32 cursor_offset = 0) const; | 281 | S32 findPixelNearestPos(S32 cursor_offset = 0) const; |
234 | void reportBadKeystroke(); | 282 | void reportBadKeystroke(); |
235 | BOOL handleSpecialKey(KEY key, MASK mask); | 283 | BOOL handleSpecialKey(KEY key, MASK mask); |
@@ -253,9 +301,20 @@ private: | |||
253 | virtual S32 getPreeditFontSize() const; | 301 | virtual S32 getPreeditFontSize() const; |
254 | 302 | ||
255 | protected: | 303 | protected: |
304 | LLHandle<LLView> mPopupMenuHandle; | ||
256 | LLUIString mText; // The string being edited. | 305 | LLUIString mText; // The string being edited. |
257 | std::string mPrevText; // Saved string for 'ESC' revert | 306 | std::string mPrevText; // Saved string for 'ESC' revert |
258 | LLUIString mLabel; // text label that is visible when no user text provided | 307 | LLUIString mLabel; // text label that is visible when no user text provided |
308 | std::string mPrevSpelledText; // saved string so we know whether to respell or not | ||
309 | std::vector<S32> mMisspellLocations; // where all the mispelled words are | ||
310 | S32 mStartSpellHere; // the position of the first char on the screen, stored so we know when to update | ||
311 | S32 mEndSpellHere; // the location of the last char on the screen | ||
312 | BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field | ||
313 | LLFrameTimer mSpellTimer; | ||
314 | //to keep track of what we have to remove before showing menu | ||
315 | std::vector<SpellMenuBind* > suggestionMenuItems; | ||
316 | S32 mLastContextMenuX; | ||
317 | BOOL mAllowTranslate; // set in xui as "allow_translate". | ||
259 | 318 | ||
260 | // line history support: | 319 | // line history support: |
261 | BOOL mHaveHistory; // flag for enabled line history | 320 | BOOL mHaveHistory; // flag for enabled line history |
@@ -364,6 +423,8 @@ private: | |||
364 | BOOL mIsSelecting; | 423 | BOOL mIsSelecting; |
365 | S32 mSelectionStart; | 424 | S32 mSelectionStart; |
366 | S32 mSelectionEnd; | 425 | S32 mSelectionEnd; |
426 | |||
427 | |||
367 | }; // end class LLLineEditorRollback | 428 | }; // end class LLLineEditorRollback |
368 | 429 | ||
369 | }; // end class LLLineEditor | 430 | }; // end class LLLineEditor |
@@ -410,4 +471,6 @@ private: | |||
410 | 471 | ||
411 | }; | 472 | }; |
412 | 473 | ||
474 | |||
475 | |||
413 | #endif // LL_LINEEDITOR_ | 476 | #endif // LL_LINEEDITOR_ |
diff --git a/linden/indra/llui/llmenugl.cpp b/linden/indra/llui/llmenugl.cpp index b70f98b..d5e1186 100644 --- a/linden/indra/llui/llmenugl.cpp +++ b/linden/indra/llui/llmenugl.cpp | |||
@@ -101,8 +101,8 @@ const U32 SEPARATOR_HEIGHT_PIXELS = 8; | |||
101 | const S32 TEAROFF_SEPARATOR_HEIGHT_PIXELS = 10; | 101 | const S32 TEAROFF_SEPARATOR_HEIGHT_PIXELS = 10; |
102 | const S32 MENU_ITEM_PADDING = 4; | 102 | const S32 MENU_ITEM_PADDING = 4; |
103 | 103 | ||
104 | const std::string BOOLEAN_TRUE_PREFIX( "X" ); | 104 | const std::string BOOLEAN_TRUE_PREFIX( "\xe2\x9c\x93" ); // U+2714 -- MC |
105 | const std::string BRANCH_SUFFIX( ">" ); | 105 | const std::string BRANCH_SUFFIX( "\xE2\x96\xB6" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE |
106 | const std::string ARROW_UP ("^^^^^^^"); | 106 | const std::string ARROW_UP ("^^^^^^^"); |
107 | const std::string ARROW_DOWN("vvvvvvv"); | 107 | const std::string ARROW_DOWN("vvvvvvv"); |
108 | 108 | ||
@@ -149,6 +149,18 @@ LLMenuItemGL::LLMenuItemGL( const std::string& name, const std::string& label, K | |||
149 | setLabel( label ); | 149 | setLabel( label ); |
150 | } | 150 | } |
151 | 151 | ||
152 | LLMenuItemGL::~LLMenuItemGL() { | ||
153 | |||
154 | // Delete all the entries in the mFutureCallbackRequests vector | ||
155 | for(std::vector<LLCallbackInformation*>::iterator iter= mFutureCallbackRequests.begin(); | ||
156 | iter!=mFutureCallbackRequests.end(); | ||
157 | ++iter) { | ||
158 | delete (*iter); | ||
159 | } | ||
160 | |||
161 | } | ||
162 | |||
163 | |||
152 | // virtual | 164 | // virtual |
153 | LLXMLNodePtr LLMenuItemGL::getXML(bool save_children) const | 165 | LLXMLNodePtr LLMenuItemGL::getXML(bool save_children) const |
154 | { | 166 | { |
@@ -517,6 +529,18 @@ BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit& | |||
517 | return TRUE; | 529 | return TRUE; |
518 | } | 530 | } |
519 | 531 | ||
532 | |||
533 | void LLMenuItemGL::addCallbackType(U8 theType, | ||
534 | const std::string& name, | ||
535 | const std::string& userdata) { | ||
536 | |||
537 | // Add the new callback information to the list of callbacks that are being tracked. | ||
538 | mFutureCallbackRequests.push_back(new LLCallbackInformation(theType,name,userdata)); | ||
539 | |||
540 | } | ||
541 | |||
542 | |||
543 | |||
520 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 544 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
521 | // Class LLMenuItemSeparatorGL | 545 | // Class LLMenuItemSeparatorGL |
522 | // | 546 | // |
@@ -541,6 +565,12 @@ public: | |||
541 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); | 565 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); |
542 | 566 | ||
543 | virtual U32 getNominalHeight( void ) const { return SEPARATOR_HEIGHT_PIXELS; } | 567 | virtual U32 getNominalHeight( void ) const { return SEPARATOR_HEIGHT_PIXELS; } |
568 | |||
569 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
570 | const std::string& name, | ||
571 | void* user_data, | ||
572 | void *callback_fcn) { return FALSE; } ; | ||
573 | |||
544 | }; | 574 | }; |
545 | 575 | ||
546 | LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const std::string &name ) : | 576 | LLMenuItemSeparatorGL::LLMenuItemSeparatorGL( const std::string &name ) : |
@@ -726,6 +756,11 @@ public: | |||
726 | } | 756 | } |
727 | virtual void doIt( void ) {} | 757 | virtual void doIt( void ) {} |
728 | virtual void draw( void ) {} | 758 | virtual void draw( void ) {} |
759 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
760 | const std::string& name, | ||
761 | void* user_data, | ||
762 | void *callback_fcn) { return FALSE; } ; | ||
763 | |||
729 | }; | 764 | }; |
730 | 765 | ||
731 | 766 | ||
@@ -805,6 +840,8 @@ LLMenuItemCallGL::LLMenuItemCallGL(const std::string& name, | |||
805 | if(!enabled) setEnabled(FALSE); | 840 | if(!enabled) setEnabled(FALSE); |
806 | } | 841 | } |
807 | 842 | ||
843 | |||
844 | |||
808 | void LLMenuItemCallGL::setEnabledControl(std::string enabled_control, LLView *context) | 845 | void LLMenuItemCallGL::setEnabledControl(std::string enabled_control, LLView *context) |
809 | { | 846 | { |
810 | // Register new listener | 847 | // Register new listener |
@@ -921,6 +958,53 @@ BOOL LLMenuItemCallGL::handleAcceleratorKey( KEY key, MASK mask ) | |||
921 | return LLMenuItemGL::handleAcceleratorKey(key, mask); | 958 | return LLMenuItemGL::handleAcceleratorKey(key, mask); |
922 | } | 959 | } |
923 | 960 | ||
961 | |||
962 | |||
963 | // Method to add a callback function for the given type and name. | ||
964 | BOOL LLMenuItemCallGL::setCtrlResponse(U8 llMenuItemCallType, | ||
965 | const std::string& name, | ||
966 | void* user_data, | ||
967 | void *callback_fcn) { | ||
968 | |||
969 | // Loop through all of the menu items and check to see which ones | ||
970 | // match the name and callback type given. | ||
971 | BOOL result = FALSE; | ||
972 | std::vector<LLCallbackInformation*>::iterator item_iter; | ||
973 | for (item_iter = mFutureCallbackRequests.begin(); | ||
974 | item_iter != mFutureCallbackRequests.end(); | ||
975 | ++item_iter) | ||
976 | { | ||
977 | if( ((*item_iter)->getTypeOfCallback()==llMenuItemCallType) && | ||
978 | ((*item_iter)->getCallbackName()==name)) { | ||
979 | |||
980 | // Found a match. Set the user data and then determine what type it is. | ||
981 | setUserData(user_data); | ||
982 | |||
983 | if(llMenuItemCallType == LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK) | ||
984 | { | ||
985 | setMenuCallback((menu_callback)callback_fcn,user_data); | ||
986 | } | ||
987 | |||
988 | else if (llMenuItemCallType == LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE) | ||
989 | { | ||
990 | setEnabledCallback((enabled_callback)callback_fcn); | ||
991 | } | ||
992 | |||
993 | else if (llMenuItemCallType == LLCallbackInformation::LL_MENU_ITEM_CALL_GL_TRANSLATE) { | ||
994 | setName((*item_iter)->getCallbackUserData()); | ||
995 | setMenuCallback((menu_callback)callback_fcn,user_data); | ||
996 | } | ||
997 | |||
998 | } | ||
999 | } | ||
1000 | |||
1001 | |||
1002 | return result; | ||
1003 | |||
1004 | } | ||
1005 | |||
1006 | |||
1007 | |||
924 | ///============================================================================ | 1008 | ///============================================================================ |
925 | /// Class LLMenuItemCheckGL | 1009 | /// Class LLMenuItemCheckGL |
926 | ///============================================================================ | 1010 | ///============================================================================ |
@@ -1379,6 +1463,17 @@ void LLMenuItemBranchGL::openMenu() | |||
1379 | } | 1463 | } |
1380 | 1464 | ||
1381 | 1465 | ||
1466 | BOOL LLMenuItemBranchGL::setCtrlResponse(U8 llMenuItemCallType, | ||
1467 | const std::string& name, | ||
1468 | void* user_data, | ||
1469 | void *callback_fcn) { | ||
1470 | |||
1471 | // Get the menu branch and set the callback functions on all its children. | ||
1472 | return(getBranch()->setCtrlResponse(llMenuItemCallType,name,user_data,callback_fcn)); | ||
1473 | |||
1474 | } | ||
1475 | |||
1476 | |||
1382 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 1477 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1383 | // Class LLMenuItemBranchDownGL | 1478 | // Class LLMenuItemBranchDownGL |
1384 | // | 1479 | // |
@@ -1982,13 +2077,31 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory | |||
1982 | 2077 | ||
1983 | LLSimpleListener* callback = parent->getListenerByName(callback_name); | 2078 | LLSimpleListener* callback = parent->getListenerByName(callback_name); |
1984 | 2079 | ||
1985 | if (!callback) | 2080 | if (callback) |
1986 | { | 2081 | { |
1987 | lldebugs << "Ignoring \"on_click\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl; | 2082 | new_item->addListener(callback, "on_click", callback_data); |
1988 | continue; | 2083 | } |
2084 | else { | ||
2085 | |||
2086 | // A callback for this item has not yet been | ||
2087 | // specified. Add it to the list of options | ||
2088 | // that do not yet have callbacks. | ||
2089 | if (call_child->hasAttribute("translate")) | ||
2090 | { | ||
2091 | new_item->addCallbackType | ||
2092 | (LLCallbackInformation::LL_MENU_ITEM_CALL_GL_TRANSLATE, | ||
2093 | item_name, | ||
2094 | callback_data); | ||
2095 | } | ||
2096 | |||
2097 | else | ||
2098 | { | ||
2099 | new_item->addCallbackType | ||
2100 | (LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
2101 | item_name, | ||
2102 | callback_data); | ||
2103 | } | ||
1989 | } | 2104 | } |
1990 | |||
1991 | new_item->addListener(callback, "on_click", callback_data); | ||
1992 | } | 2105 | } |
1993 | if (call_child->hasName("on_enable")) | 2106 | if (call_child->hasName("on_enable")) |
1994 | { | 2107 | { |
@@ -2016,13 +2129,22 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory | |||
2016 | 2129 | ||
2017 | LLSimpleListener* callback = parent->getListenerByName(callback_name); | 2130 | LLSimpleListener* callback = parent->getListenerByName(callback_name); |
2018 | 2131 | ||
2019 | if (!callback) | 2132 | if (callback) |
2020 | { | 2133 | { |
2021 | lldebugs << "Ignoring \"on_enable\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl; | 2134 | new_item->addListener(callback, "on_build", userdata); |
2022 | continue; | 2135 | } else { |
2136 | |||
2137 | // A callback for this item has not yet been | ||
2138 | // specified. Add it to the list of options | ||
2139 | // that do not yet have callbacks. | ||
2140 | |||
2141 | new_item->addCallbackType | ||
2142 | (LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
2143 | item_name, | ||
2144 | callback_data); | ||
2023 | } | 2145 | } |
2024 | 2146 | ||
2025 | new_item->addListener(callback, "on_build", userdata); | 2147 | |
2026 | } | 2148 | } |
2027 | else if (call_child->hasAttribute("control")) | 2149 | else if (call_child->hasAttribute("control")) |
2028 | { | 2150 | { |
@@ -2188,7 +2310,7 @@ LLView* LLMenuGL::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa | |||
2188 | LLColor4 color(0,0,0,1); | 2310 | LLColor4 color(0,0,0,1); |
2189 | if (opaque && LLUICtrlFactory::getAttributeColor(node,"color", color)) | 2311 | if (opaque && LLUICtrlFactory::getAttributeColor(node,"color", color)) |
2190 | { | 2312 | { |
2191 | menu->setBackgroundColor(color); | 2313 | menu->setBackgroundColor(color); |
2192 | } | 2314 | } |
2193 | 2315 | ||
2194 | BOOL create_jump_keys = FALSE; | 2316 | BOOL create_jump_keys = FALSE; |
@@ -2582,6 +2704,31 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) | |||
2582 | return success; | 2704 | return success; |
2583 | } | 2705 | } |
2584 | 2706 | ||
2707 | // Remove a menu item from this menu. | ||
2708 | BOOL LLMenuGL::remove( LLMenuItemGL* item ) | ||
2709 | { | ||
2710 | if (mSpilloverMenu) | ||
2711 | { | ||
2712 | cleanupSpilloverBranch(); | ||
2713 | } | ||
2714 | |||
2715 | item_list_t::iterator found_iter = std::find(mItems.begin(), mItems.end(), item); | ||
2716 | if (found_iter != mItems.end()) | ||
2717 | { | ||
2718 | mItems.erase(found_iter); | ||
2719 | } | ||
2720 | |||
2721 | removeChild( item ); | ||
2722 | |||
2723 | // We keep it around in case someone is pointing at it. | ||
2724 | // The caller can delete it if it's safe. | ||
2725 | // Note that getMenu() will still not work since its parent isn't a menu. | ||
2726 | sMenuContainer->addChild( item ); | ||
2727 | |||
2728 | arrange(); | ||
2729 | return TRUE; | ||
2730 | } | ||
2731 | |||
2585 | void LLMenuGL::setEnabledSubMenus(BOOL enable) | 2732 | void LLMenuGL::setEnabledSubMenus(BOOL enable) |
2586 | { | 2733 | { |
2587 | setEnabled(enable); | 2734 | setEnabled(enable); |
@@ -2952,7 +3099,8 @@ void LLMenuGL::draw( void ) | |||
2952 | 3099 | ||
2953 | if( mBgVisible ) | 3100 | if( mBgVisible ) |
2954 | { | 3101 | { |
2955 | gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0, mBackgroundColor ); | 3102 | gl_rect_2d( -1, getRect().getHeight()+2, getRect().getWidth()+2, -2, mBorderColor,FALSE); |
3103 | gl_rect_2d( 0, getRect().getHeight(), getRect().getWidth(), 0, mBackgroundColor ); | ||
2956 | } | 3104 | } |
2957 | LLView::draw(); | 3105 | LLView::draw(); |
2958 | } | 3106 | } |
@@ -3008,6 +3156,41 @@ LLMenuGL* LLMenuGL::getChildMenuByName(const std::string& name, BOOL recurse) co | |||
3008 | return NULL; | 3156 | return NULL; |
3009 | } | 3157 | } |
3010 | 3158 | ||
3159 | |||
3160 | void LLMenuGL::setBackgroundColor( const LLColor4& color ) { | ||
3161 | |||
3162 | mBackgroundColor = color; | ||
3163 | item_list_t::iterator item_iter; | ||
3164 | for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) | ||
3165 | { | ||
3166 | if((*item_iter)->getType()=="menu") | ||
3167 | { | ||
3168 | LLMenuItemBranchGL *menuBranchItem = (LLMenuItemBranchGL*)(*item_iter); | ||
3169 | menuBranchItem->getBranch()->setBackgroundColor(color); | ||
3170 | } | ||
3171 | } | ||
3172 | |||
3173 | |||
3174 | } | ||
3175 | |||
3176 | |||
3177 | void LLMenuGL::setBorderColor( const LLColor4& color ) { | ||
3178 | |||
3179 | mBorderColor = color; | ||
3180 | item_list_t::iterator item_iter; | ||
3181 | for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) | ||
3182 | { | ||
3183 | if((*item_iter)->getType()=="menu") | ||
3184 | { | ||
3185 | LLMenuItemBranchGL *menuBranchItem = (LLMenuItemBranchGL*)(*item_iter); | ||
3186 | menuBranchItem->getBranch()->setBorderColor(color); | ||
3187 | } | ||
3188 | } | ||
3189 | |||
3190 | |||
3191 | } | ||
3192 | |||
3193 | |||
3011 | BOOL LLMenuGL::clearHoverItem() | 3194 | BOOL LLMenuGL::clearHoverItem() |
3012 | { | 3195 | { |
3013 | for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) | 3196 | for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) |
@@ -3073,6 +3256,26 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) | |||
3073 | menu->getParent()->sendChildToFront(menu); | 3256 | menu->getParent()->sendChildToFront(menu); |
3074 | } | 3257 | } |
3075 | 3258 | ||
3259 | |||
3260 | BOOL LLMenuGL::setCtrlResponse(U8 llMenuItemCallType, | ||
3261 | const std::string& name, | ||
3262 | void* user_data, | ||
3263 | void *callback_fcn) | ||
3264 | { | ||
3265 | |||
3266 | // Go through all of the children on this menu and set the callback function. | ||
3267 | BOOL result = FALSE; | ||
3268 | item_list_t::iterator item_iter; | ||
3269 | for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter) | ||
3270 | { | ||
3271 | result |= (*item_iter)->setCtrlResponse(llMenuItemCallType,name,user_data,callback_fcn); | ||
3272 | } | ||
3273 | |||
3274 | return result; | ||
3275 | } | ||
3276 | |||
3277 | |||
3278 | |||
3076 | //----------------------------------------------------------------------------- | 3279 | //----------------------------------------------------------------------------- |
3077 | // class LLPieMenuBranch | 3280 | // class LLPieMenuBranch |
3078 | // A branch to another pie menu | 3281 | // A branch to another pie menu |
@@ -3092,6 +3295,12 @@ public: | |||
3092 | 3295 | ||
3093 | LLPieMenu* getBranch() { return mBranch; } | 3296 | LLPieMenu* getBranch() { return mBranch; } |
3094 | 3297 | ||
3298 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
3299 | const std::string& name, | ||
3300 | void* user_data, | ||
3301 | void *callback_fcn) { return FALSE; } ; | ||
3302 | |||
3303 | |||
3095 | protected: | 3304 | protected: |
3096 | LLPieMenu* mBranch; | 3305 | LLPieMenu* mBranch; |
3097 | }; | 3306 | }; |
@@ -4556,3 +4765,16 @@ void LLTearOffMenu::onClose(bool app_quitting) | |||
4556 | destroy(); | 4765 | destroy(); |
4557 | } | 4766 | } |
4558 | 4767 | ||
4768 | |||
4769 | ///============================================================================ | ||
4770 | /// Class LLCallbackInformation | ||
4771 | ///============================================================================ | ||
4772 | |||
4773 | LLCallbackInformation::LLCallbackInformation(U8 theType, | ||
4774 | const std::string& theName, | ||
4775 | const std::string& userData) | ||
4776 | : callbackName(theName), | ||
4777 | callbackUserData(userData) | ||
4778 | { | ||
4779 | setTypeOfCallback(theType); | ||
4780 | } | ||
diff --git a/linden/indra/llui/llmenugl.h b/linden/indra/llui/llmenugl.h index 26fc294..9a9d1b0 100644 --- a/linden/indra/llui/llmenugl.h +++ b/linden/indra/llui/llmenugl.h | |||
@@ -70,6 +70,57 @@ typedef BOOL (*check_callback)(void*); | |||
70 | // contents. Put the contents of the label in the provided parameter. | 70 | // contents. Put the contents of the label in the provided parameter. |
71 | typedef void (*label_callback)(std::string&,void*); | 71 | typedef void (*label_callback)(std::string&,void*); |
72 | 72 | ||
73 | |||
74 | |||
75 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
76 | // Class LLCallbackInformation | ||
77 | // | ||
78 | // The LLCallbackInformation class is used to keep track of callback | ||
79 | // information for menus that might be requested at a future time. | ||
80 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
81 | |||
82 | class LLCallbackInformation | ||
83 | { | ||
84 | |||
85 | public : | ||
86 | |||
87 | // Constants used for keeping track of what type of callback is required. | ||
88 | static const U8 LL_MENU_ITEM_CALL_GL_NONE = 0; | ||
89 | static const U8 LL_MENU_ITEM_CALL_GL_ON_CLICK = 1; | ||
90 | static const U8 LL_MENU_ITEM_CALL_GL_ON_ENABLE = 2; | ||
91 | static const U8 LL_MENU_ITEM_CALL_GL_TRANSLATE = 3; | ||
92 | |||
93 | |||
94 | LLCallbackInformation(U8 theType=LLCallbackInformation::LL_MENU_ITEM_CALL_GL_NONE, | ||
95 | const std::string& theName = LLStringUtil::null, | ||
96 | const std::string& userData = LLStringUtil::null); | ||
97 | ~LLCallbackInformation() {}; | ||
98 | |||
99 | void setTypeOfCallback(U8 theType) {typeOfCallback = theType; } | ||
100 | void setCallbackName(const std::string& name) {callbackName = name; } | ||
101 | void setCallbackUserData(const std::string& userdata) {callbackUserData = userdata; } | ||
102 | |||
103 | U8 getTypeOfCallback() {return(typeOfCallback); } | ||
104 | const std::string& getCallbackName() {return(callbackName); } | ||
105 | const std::string& getCallbackUserData() {return(callbackUserData); } | ||
106 | |||
107 | BOOL isTypeMatch(U8 type) { return(type == typeOfCallback);} | ||
108 | BOOL isNameMatch(const std::string& name) { return(name == callbackName);} | ||
109 | |||
110 | protected: | ||
111 | |||
112 | private: | ||
113 | |||
114 | U8 typeOfCallback; | ||
115 | std::string callbackName; | ||
116 | std::string callbackUserData; | ||
117 | |||
118 | }; | ||
119 | |||
120 | |||
121 | |||
122 | |||
123 | |||
73 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 124 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
74 | // Class LLMenuItemGL | 125 | // Class LLMenuItemGL |
75 | // | 126 | // |
@@ -79,6 +130,7 @@ typedef void (*label_callback)(std::string&,void*); | |||
79 | class LLMenuItemGL : public LLView | 130 | class LLMenuItemGL : public LLView |
80 | { | 131 | { |
81 | public: | 132 | public: |
133 | |||
82 | // static functions to control the global color scheme. | 134 | // static functions to control the global color scheme. |
83 | static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; } | 135 | static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; } |
84 | static const LLColor4& getEnabledColor() { return sEnabledColor; } | 136 | static const LLColor4& getEnabledColor() { return sEnabledColor; } |
@@ -90,7 +142,7 @@ public: | |||
90 | static const LLColor4& getHighlightFGColor() { return sHighlightForeground; } | 142 | static const LLColor4& getHighlightFGColor() { return sHighlightForeground; } |
91 | 143 | ||
92 | LLMenuItemGL( const std::string& name, const std::string& label, KEY key = KEY_NONE, MASK = MASK_NONE ); | 144 | LLMenuItemGL( const std::string& name, const std::string& label, KEY key = KEY_NONE, MASK = MASK_NONE ); |
93 | virtual ~LLMenuItemGL() {}; | 145 | virtual ~LLMenuItemGL(); |
94 | 146 | ||
95 | virtual void setValue(const LLSD& value) { setLabel(value.asString()); } | 147 | virtual void setValue(const LLSD& value) { setLabel(value.asString()); } |
96 | 148 | ||
@@ -174,6 +226,14 @@ public: | |||
174 | void setDrawTextDisabled(BOOL disabled) { mDrawTextDisabled = disabled; } | 226 | void setDrawTextDisabled(BOOL disabled) { mDrawTextDisabled = disabled; } |
175 | BOOL getDrawTextDisabled() const { return mDrawTextDisabled; } | 227 | BOOL getDrawTextDisabled() const { return mDrawTextDisabled; } |
176 | 228 | ||
229 | // functionality for adding callbacks after the menu is constucted | ||
230 | void addCallbackType(U8 theType,const std::string& name,const std::string& userdata); | ||
231 | |||
232 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
233 | const std::string& name, | ||
234 | void* user_data, | ||
235 | void *callback_fcn) = 0; | ||
236 | |||
177 | protected: | 237 | protected: |
178 | void setHover(BOOL hover) { mGotHover = hover; } | 238 | void setHover(BOOL hover) { mGotHover = hover; } |
179 | 239 | ||
@@ -194,6 +254,11 @@ protected: | |||
194 | LLUIString mDrawBranchLabel; | 254 | LLUIString mDrawBranchLabel; |
195 | 255 | ||
196 | BOOL mHighlight; | 256 | BOOL mHighlight; |
257 | |||
258 | // variables used for tracking callback types that will be | ||
259 | // requested after the widget is in place. | ||
260 | std::vector<LLCallbackInformation*> mFutureCallbackRequests; | ||
261 | |||
197 | private: | 262 | private: |
198 | static LLColor4 sEnabledColor; | 263 | static LLColor4 sEnabledColor; |
199 | static LLColor4 sDisabledColor; | 264 | static LLColor4 sDisabledColor; |
@@ -214,6 +279,7 @@ private: | |||
214 | BOOL mDrawTextDisabled; | 279 | BOOL mDrawTextDisabled; |
215 | 280 | ||
216 | KEY mJumpKey; | 281 | KEY mJumpKey; |
282 | |||
217 | }; | 283 | }; |
218 | 284 | ||
219 | 285 | ||
@@ -262,6 +328,7 @@ public: | |||
262 | KEY key = KEY_NONE, MASK mask = MASK_NONE, | 328 | KEY key = KEY_NONE, MASK mask = MASK_NONE, |
263 | BOOL enabled = TRUE, | 329 | BOOL enabled = TRUE, |
264 | on_disabled_callback on_disabled_c = NULL); | 330 | on_disabled_callback on_disabled_c = NULL); |
331 | |||
265 | virtual LLXMLNodePtr getXML(bool save_children = true) const; | 332 | virtual LLXMLNodePtr getXML(bool save_children = true) const; |
266 | 333 | ||
267 | virtual std::string getType() const { return "call"; } | 334 | virtual std::string getType() const { return "call"; } |
@@ -288,6 +355,13 @@ public: | |||
288 | 355 | ||
289 | //virtual void draw(); | 356 | //virtual void draw(); |
290 | 357 | ||
358 | // Functionality for tracking callback types for setting after widget is in place. | ||
359 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
360 | const std::string& name, | ||
361 | void* user_data, | ||
362 | void *callback_fcn); | ||
363 | |||
364 | |||
291 | 365 | ||
292 | private: | 366 | private: |
293 | menu_callback mCallback; | 367 | menu_callback mCallback; |
@@ -382,6 +456,12 @@ public: | |||
382 | // LLView Functionality | 456 | // LLView Functionality |
383 | //virtual void draw( void ); | 457 | //virtual void draw( void ); |
384 | 458 | ||
459 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
460 | const std::string& name, | ||
461 | void* user_data, | ||
462 | void *callback_fcn) { return FALSE; } ; | ||
463 | |||
464 | |||
385 | private: | 465 | private: |
386 | BOOL* mToggle; | 466 | BOOL* mToggle; |
387 | }; | 467 | }; |
@@ -434,14 +514,19 @@ public: | |||
434 | 514 | ||
435 | // background colors | 515 | // background colors |
436 | static void setDefaultBackgroundColor( const LLColor4& color ) { sDefaultBackgroundColor = color; } | 516 | static void setDefaultBackgroundColor( const LLColor4& color ) { sDefaultBackgroundColor = color; } |
437 | void setBackgroundColor( const LLColor4& color ) { mBackgroundColor = color; } | 517 | void setBackgroundColor( const LLColor4& color ); |
518 | void setBorderColor( const LLColor4& color ); | ||
438 | const LLColor4& getBackgroundColor() const { return mBackgroundColor; } | 519 | const LLColor4& getBackgroundColor() const { return mBackgroundColor; } |
520 | const LLColor4& getBorderColor() const { return mBorderColor; } | ||
439 | void setBackgroundVisible( BOOL b ) { mBgVisible = b; } | 521 | void setBackgroundVisible( BOOL b ) { mBgVisible = b; } |
440 | void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); | 522 | void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>()); |
441 | 523 | ||
442 | // Add the menu item to this menu. | 524 | // Add the menu item to this menu. |
443 | virtual BOOL append( LLMenuItemGL* item ); | 525 | virtual BOOL append( LLMenuItemGL* item ); |
444 | 526 | ||
527 | // Remove a menu item from this menu. | ||
528 | virtual BOOL remove( LLMenuItemGL* item ); | ||
529 | |||
445 | // *NOTE:Mani - appendNoArrange() should be removed when merging to skinning/viewer2.0 | 530 | // *NOTE:Mani - appendNoArrange() should be removed when merging to skinning/viewer2.0 |
446 | // Its added as a fix to a viewer 1.23 bug that has already been address by skinning work. | 531 | // Its added as a fix to a viewer 1.23 bug that has already been address by skinning work. |
447 | virtual BOOL appendNoArrange( LLMenuItemGL* item ); | 532 | virtual BOOL appendNoArrange( LLMenuItemGL* item ); |
@@ -522,6 +607,8 @@ public: | |||
522 | static BOOL getKeyboardMode() { return sKeyboardMode; } | 607 | static BOOL getKeyboardMode() { return sKeyboardMode; } |
523 | 608 | ||
524 | static class LLMenuHolderGL* sMenuContainer; | 609 | static class LLMenuHolderGL* sMenuContainer; |
610 | |||
611 | BOOL setCtrlResponse(U8 llMenuItemCallType,const std::string& name,void* user_data,void *callback_fcn); | ||
525 | 612 | ||
526 | protected: | 613 | protected: |
527 | void createSpilloverBranch(); | 614 | void createSpilloverBranch(); |
@@ -544,6 +631,7 @@ private: | |||
544 | static BOOL sKeyboardMode; | 631 | static BOOL sKeyboardMode; |
545 | 632 | ||
546 | LLColor4 mBackgroundColor; | 633 | LLColor4 mBackgroundColor; |
634 | LLColor4 mBorderColor; | ||
547 | BOOL mBgVisible; | 635 | BOOL mBgVisible; |
548 | LLMenuItemGL* mParentMenuItem; | 636 | LLMenuItemGL* mParentMenuItem; |
549 | LLUIString mLabel; | 637 | LLUIString mLabel; |
@@ -620,6 +708,12 @@ public: | |||
620 | 708 | ||
621 | virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; | 709 | virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; |
622 | 710 | ||
711 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
712 | const std::string& name, | ||
713 | void* user_data, | ||
714 | void *callback_fcn); | ||
715 | |||
716 | |||
623 | private: | 717 | private: |
624 | LLHandle<LLView> mBranch; | 718 | LLHandle<LLView> mBranch; |
625 | }; // end class LLMenuItemBranchGL | 719 | }; // end class LLMenuItemBranchGL |
@@ -665,6 +759,12 @@ public: | |||
665 | void show(S32 x, S32 y, BOOL mouse_down); | 759 | void show(S32 x, S32 y, BOOL mouse_down); |
666 | void hide(BOOL item_selected); | 760 | void hide(BOOL item_selected); |
667 | 761 | ||
762 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
763 | const std::string& name, | ||
764 | void* user_data, | ||
765 | void *callback_fcn) { return FALSE; } ; | ||
766 | |||
767 | |||
668 | private: | 768 | private: |
669 | LLMenuItemGL *pieItemFromXY(S32 x, S32 y); | 769 | LLMenuItemGL *pieItemFromXY(S32 x, S32 y); |
670 | S32 pieItemIndexFromXY(S32 x, S32 y); | 770 | S32 pieItemIndexFromXY(S32 x, S32 y); |
@@ -726,6 +826,12 @@ public: | |||
726 | 826 | ||
727 | void resetMenuTrigger() { mAltKeyTrigger = FALSE; } | 827 | void resetMenuTrigger() { mAltKeyTrigger = FALSE; } |
728 | 828 | ||
829 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
830 | const std::string& name, | ||
831 | void* user_data, | ||
832 | void *callback_fcn) { return FALSE; } ; | ||
833 | |||
834 | |||
729 | private: | 835 | private: |
730 | void checkMenuTrigger(); | 836 | void checkMenuTrigger(); |
731 | 837 | ||
@@ -811,6 +917,12 @@ public: | |||
811 | virtual void draw(void); | 917 | virtual void draw(void); |
812 | virtual U32 getNominalHeight() const; | 918 | virtual U32 getNominalHeight() const; |
813 | 919 | ||
920 | virtual BOOL setCtrlResponse(U8 llMenuItemCallType, | ||
921 | const std::string& name, | ||
922 | void* user_data, | ||
923 | void *callback_fcn) { return FALSE; } ; | ||
924 | |||
925 | |||
814 | private: | 926 | private: |
815 | LLHandle<LLFloater> mParentHandle; | 927 | LLHandle<LLFloater> mParentHandle; |
816 | }; | 928 | }; |
@@ -829,4 +941,5 @@ private: | |||
829 | LLEditMenuHandlerMgr() {}; | 941 | LLEditMenuHandlerMgr() {}; |
830 | }; | 942 | }; |
831 | 943 | ||
944 | |||
832 | #endif // LL_LLMENUGL_H | 945 | #endif // LL_LLMENUGL_H |
diff --git a/linden/indra/llui/llmultisliderctrl.cpp b/linden/indra/llui/llmultisliderctrl.cpp index b76c2f6..f9ec6d5 100644 --- a/linden/indra/llui/llmultisliderctrl.cpp +++ b/linden/indra/llui/llmultisliderctrl.cpp | |||
@@ -34,9 +34,6 @@ | |||
34 | 34 | ||
35 | #include "llmultisliderctrl.h" | 35 | #include "llmultisliderctrl.h" |
36 | 36 | ||
37 | #include "audioengine.h" | ||
38 | #include "sound_ids.h" | ||
39 | |||
40 | #include "llmath.h" | 37 | #include "llmath.h" |
41 | #include "llfontgl.h" | 38 | #include "llfontgl.h" |
42 | #include "llgl.h" | 39 | #include "llgl.h" |
diff --git a/linden/indra/llui/llnotifications.cpp b/linden/indra/llui/llnotifications.cpp index 2459110..77f2ff7 100644 --- a/linden/indra/llui/llnotifications.cpp +++ b/linden/indra/llui/llnotifications.cpp | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <algorithm> | 40 | #include <algorithm> |
41 | #include <boost/regex.hpp> | 41 | #include <boost/regex.hpp> |
42 | 42 | ||
43 | #include "../newview/hippoGridManager.h" | 43 | #include "../newview/hippogridmanager.h" |
44 | 44 | ||
45 | 45 | ||
46 | const std::string NOTIFICATION_PERSIST_VERSION = "0.93"; | 46 | const std::string NOTIFICATION_PERSIST_VERSION = "0.93"; |
@@ -1190,13 +1190,13 @@ void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements) | |||
1190 | if (found != replacements.end()) | 1190 | if (found != replacements.end()) |
1191 | { | 1191 | { |
1192 | replacement = found->second; | 1192 | replacement = found->second; |
1193 | //llwarns << "replaceSubstituionStrings: value: " << value << " repl: " << replacement << llendl; | 1193 | //llinfos << "replaceSubstitutionStrings: value: \"" << value << "\" repl: \"" << replacement << "\"." << llendl; |
1194 | 1194 | ||
1195 | it->second->setValue(replacement); | 1195 | it->second->setValue(replacement); |
1196 | } | 1196 | } |
1197 | else | 1197 | else |
1198 | { | 1198 | { |
1199 | llwarns << "replaceSubstituionStrings FAILURE: value: " << value << " repl: " << replacement << llendl; | 1199 | llwarns << "replaceSubstitutionStrings FAILURE: could not find replacement \"" << value << "\"." << llendl; |
1200 | } | 1200 | } |
1201 | } | 1201 | } |
1202 | } | 1202 | } |
diff --git a/linden/indra/llui/llpanel.cpp b/linden/indra/llui/llpanel.cpp index 709342b..07e78ed 100644 --- a/linden/indra/llui/llpanel.cpp +++ b/linden/indra/llui/llpanel.cpp | |||
@@ -203,6 +203,12 @@ void LLPanel::draw() | |||
203 | LLView::draw(); | 203 | LLView::draw(); |
204 | } | 204 | } |
205 | 205 | ||
206 | /*virtual*/ | ||
207 | void LLPanel::setAlpha(F32 alpha) | ||
208 | { | ||
209 | mBgColorOpaque.setAlpha(alpha); | ||
210 | } | ||
211 | |||
206 | void LLPanel::updateDefaultBtn() | 212 | void LLPanel::updateDefaultBtn() |
207 | { | 213 | { |
208 | // This method does not call LLView::draw() so callers will need | 214 | // This method does not call LLView::draw() so callers will need |
@@ -213,8 +219,7 @@ void LLPanel::updateDefaultBtn() | |||
213 | { | 219 | { |
214 | if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) | 220 | if (gFocusMgr.childHasKeyboardFocus( this ) && mDefaultBtn->getEnabled()) |
215 | { | 221 | { |
216 | LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); | 222 | LLButton* buttonp = dynamic_cast<LLButton*>(gFocusMgr.getKeyboardFocus()); |
217 | LLButton* buttonp = dynamic_cast<LLButton*>(focus_ctrl); | ||
218 | BOOL focus_is_child_button = buttonp && buttonp->getCommitOnReturn(); | 223 | BOOL focus_is_child_button = buttonp && buttonp->getCommitOnReturn(); |
219 | // only enable default button when current focus is not a return-capturing button | 224 | // only enable default button when current focus is not a return-capturing button |
220 | mDefaultBtn->setBorderEnabled(!focus_is_child_button); | 225 | mDefaultBtn->setBorderEnabled(!focus_is_child_button); |
@@ -276,7 +281,7 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask ) | |||
276 | { | 281 | { |
277 | BOOL handled = FALSE; | 282 | BOOL handled = FALSE; |
278 | 283 | ||
279 | LLUICtrl* cur_focus = gFocusMgr.getKeyboardFocus(); | 284 | LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); |
280 | 285 | ||
281 | // handle user hitting ESC to defocus | 286 | // handle user hitting ESC to defocus |
282 | if (key == KEY_ESCAPE) | 287 | if (key == KEY_ESCAPE) |
@@ -800,6 +805,14 @@ void LLPanel::childSetColor(const std::string& id, const LLColor4& color) | |||
800 | child->setColor(color); | 805 | child->setColor(color); |
801 | } | 806 | } |
802 | } | 807 | } |
808 | void LLPanel::childSetAlpha(const std::string& id, F32 alpha) | ||
809 | { | ||
810 | LLUICtrl* child = getChild<LLUICtrl>(id, true); | ||
811 | if (child) | ||
812 | { | ||
813 | child->setAlpha(alpha); | ||
814 | } | ||
815 | } | ||
803 | 816 | ||
804 | LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const std::string& id) const | 817 | LLCtrlSelectionInterface* LLPanel::childGetSelectionInterface(const std::string& id) const |
805 | { | 818 | { |
@@ -1158,7 +1171,7 @@ void LLLayoutStack::draw() | |||
1158 | 1171 | ||
1159 | LLLocalClipRect clip(clip_rect); | 1172 | LLLocalClipRect clip(clip_rect); |
1160 | // only force drawing invisible children if visible amount is non-zero | 1173 | // only force drawing invisible children if visible amount is non-zero |
1161 | drawChild(panelp, 0, 0, !clip_rect.isNull()); | 1174 | drawChild(panelp, 0, 0, !clip_rect.isEmpty()); |
1162 | } | 1175 | } |
1163 | } | 1176 | } |
1164 | 1177 | ||
diff --git a/linden/indra/llui/llpanel.h b/linden/indra/llui/llpanel.h index 756d02e..378b357 100644 --- a/linden/indra/llui/llpanel.h +++ b/linden/indra/llui/llpanel.h | |||
@@ -82,6 +82,8 @@ public: | |||
82 | 82 | ||
83 | // From LLFocusableElement | 83 | // From LLFocusableElement |
84 | /*virtual*/ void setFocus( BOOL b ); | 84 | /*virtual*/ void setFocus( BOOL b ); |
85 | virtual void setAlpha(F32 alpha); | ||
86 | |||
85 | 87 | ||
86 | // New virtuals | 88 | // New virtuals |
87 | virtual void refresh(); // called in setFocus() | 89 | virtual void refresh(); // called in setFocus() |
@@ -174,6 +176,7 @@ public: | |||
174 | void childSetUserData(const std::string& id, void* userdata); | 176 | void childSetUserData(const std::string& id, void* userdata); |
175 | 177 | ||
176 | void childSetColor(const std::string& id, const LLColor4& color); | 178 | void childSetColor(const std::string& id, const LLColor4& color); |
179 | void childSetAlpha(const std::string& id, F32 alpha); | ||
177 | 180 | ||
178 | LLCtrlSelectionInterface* childGetSelectionInterface(const std::string& id) const; | 181 | LLCtrlSelectionInterface* childGetSelectionInterface(const std::string& id) const; |
179 | LLCtrlListInterface* childGetListInterface(const std::string& id) const; | 182 | LLCtrlListInterface* childGetListInterface(const std::string& id) const; |
diff --git a/linden/indra/llui/llresmgr.cpp b/linden/indra/llui/llresmgr.cpp index 32d3d1f..22610ca 100644 --- a/linden/indra/llui/llresmgr.cpp +++ b/linden/indra/llui/llresmgr.cpp | |||
@@ -58,7 +58,8 @@ LLResMgr::LLResMgr() | |||
58 | mUSAFonts[ LLFONT_OCRA ] = LLFontGL::getFontMonospace(); | 58 | mUSAFonts[ LLFONT_OCRA ] = LLFontGL::getFontMonospace(); |
59 | mUSAFonts[ LLFONT_SANSSERIF ] = LLFontGL::getFontSansSerif(); | 59 | mUSAFonts[ LLFONT_SANSSERIF ] = LLFontGL::getFontSansSerif(); |
60 | mUSAFonts[ LLFONT_SANSSERIF_SMALL ] = LLFontGL::getFontSansSerifSmall(); | 60 | mUSAFonts[ LLFONT_SANSSERIF_SMALL ] = LLFontGL::getFontSansSerifSmall(); |
61 | mUSAFonts[ LLFONT_SANSSERIF_BIG ] = LLFontGL::getFontSansSerifBig(); | 61 | mUSAFonts[ LLFONT_SANSSERIF_BIGGER ]= LLFontGL::getFontSansSerifBigger(); |
62 | mUSAFonts[ LLFONT_SANSSERIF_LARGE ] = LLFontGL::getFontSansSerifLarge(); | ||
62 | mUSAFonts[ LLFONT_SMALL ] = LLFontGL::getFontMonospace(); | 63 | mUSAFonts[ LLFONT_SMALL ] = LLFontGL::getFontMonospace(); |
63 | /* | 64 | /* |
64 | // USA Strings | 65 | // USA Strings |
@@ -421,7 +422,8 @@ const std::string LLFONT_ID_NAMES[] = | |||
421 | std::string("OCRA"), | 422 | std::string("OCRA"), |
422 | std::string("SANSSERIF"), | 423 | std::string("SANSSERIF"), |
423 | std::string("SANSSERIF_SMALL"), | 424 | std::string("SANSSERIF_SMALL"), |
424 | std::string("SANSSERIF_BIG"), | 425 | std::string("SANSSERIF_BIGGER"), |
426 | std::string("SANSSERIF_LARGE"), | ||
425 | std::string("SMALL"), | 427 | std::string("SMALL"), |
426 | }; | 428 | }; |
427 | 429 | ||
diff --git a/linden/indra/llui/llresmgr.h b/linden/indra/llui/llresmgr.h index d54505c..3008244 100644 --- a/linden/indra/llui/llresmgr.h +++ b/linden/indra/llui/llresmgr.h | |||
@@ -51,7 +51,8 @@ enum LLFONT_ID | |||
51 | LLFONT_OCRA, | 51 | LLFONT_OCRA, |
52 | LLFONT_SANSSERIF, | 52 | LLFONT_SANSSERIF, |
53 | LLFONT_SANSSERIF_SMALL, | 53 | LLFONT_SANSSERIF_SMALL, |
54 | LLFONT_SANSSERIF_BIG, | 54 | LLFONT_SANSSERIF_BIGGER, |
55 | LLFONT_SANSSERIF_LARGE, | ||
55 | LLFONT_SMALL, | 56 | LLFONT_SMALL, |
56 | LLFONT_COUNT // Number of values in this enum. Keep at end. | 57 | LLFONT_COUNT // Number of values in this enum. Keep at end. |
57 | }; | 58 | }; |
diff --git a/linden/indra/llui/llscrollbar.cpp b/linden/indra/llui/llscrollbar.cpp index 65086d8..11e6239 100644 --- a/linden/indra/llui/llscrollbar.cpp +++ b/linden/indra/llui/llscrollbar.cpp | |||
@@ -426,6 +426,11 @@ BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) | |||
426 | changeLine( clicks * mStepSize, TRUE ); | 426 | changeLine( clicks * mStepSize, TRUE ); |
427 | return TRUE; | 427 | return TRUE; |
428 | } | 428 | } |
429 | BOOL LLScrollbar::handleHScrollWheel(S32 x, S32 y, S32 clicks) | ||
430 | { | ||
431 | changeLine( clicks * mStepSize, TRUE ); | ||
432 | return TRUE; | ||
433 | } | ||
429 | 434 | ||
430 | BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, | 435 | BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, |
431 | EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg) | 436 | EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg) |
diff --git a/linden/indra/llui/llscrollbar.h b/linden/indra/llui/llscrollbar.h index 0bbf866..6969662 100644 --- a/linden/indra/llui/llscrollbar.h +++ b/linden/indra/llui/llscrollbar.h | |||
@@ -69,6 +69,7 @@ public: | |||
69 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); | 69 | virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); |
70 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); | 70 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); |
71 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); | 71 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); |
72 | virtual BOOL handleHScrollWheel(S32 x, S32 y, S32 clicks); | ||
72 | virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, | 73 | virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, |
73 | EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg); | 74 | EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg); |
74 | 75 | ||
diff --git a/linden/indra/llui/llscrollcontainer.cpp b/linden/indra/llui/llscrollcontainer.cpp index 6f037e2..8737a70 100644 --- a/linden/indra/llui/llscrollcontainer.cpp +++ b/linden/indra/llui/llscrollcontainer.cpp | |||
@@ -239,6 +239,23 @@ BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks ) | |||
239 | return TRUE; | 239 | return TRUE; |
240 | } | 240 | } |
241 | 241 | ||
242 | BOOL LLScrollableContainerView::handleHScrollWheel( S32 x, S32 y, S32 clicks ) | ||
243 | { | ||
244 | for( S32 i = SCROLLBAR_COUNT - 1; i >= 0; i++ ) | ||
245 | { | ||
246 | // Note: tries horizontal and then vertical | ||
247 | |||
248 | // Pretend the mouse is over the scrollbar | ||
249 | if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) ) | ||
250 | { | ||
251 | return TRUE; | ||
252 | } | ||
253 | } | ||
254 | |||
255 | // Eat scroll wheel event (to avoid scrolling nested containers?) | ||
256 | return TRUE; | ||
257 | } | ||
258 | |||
242 | BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const | 259 | BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const |
243 | { | 260 | { |
244 | if(mScrollbar[axis]->getVisible()) | 261 | if(mScrollbar[axis]->getVisible()) |
diff --git a/linden/indra/llui/llscrollcontainer.h b/linden/indra/llui/llscrollcontainer.h index 70fc908..c18a0db 100644 --- a/linden/indra/llui/llscrollcontainer.h +++ b/linden/indra/llui/llscrollcontainer.h | |||
@@ -91,6 +91,7 @@ public: | |||
91 | virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); | 91 | virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); |
92 | virtual BOOL handleKeyHere(KEY key, MASK mask); | 92 | virtual BOOL handleKeyHere(KEY key, MASK mask); |
93 | virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); | 93 | virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); |
94 | virtual BOOL handleHScrollWheel( S32 x, S32 y, S32 clicks ); | ||
94 | virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, | 95 | virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, |
95 | EDragAndDropType cargo_type, | 96 | EDragAndDropType cargo_type, |
96 | void* cargo_data, | 97 | void* cargo_data, |
diff --git a/linden/indra/llui/llscrolllistctrl.cpp b/linden/indra/llui/llscrolllistctrl.cpp index 3c2293f..1b93abf 100644 --- a/linden/indra/llui/llscrolllistctrl.cpp +++ b/linden/indra/llui/llscrolllistctrl.cpp | |||
@@ -103,6 +103,10 @@ struct SortScrollListItem | |||
103 | LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width) | 103 | LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width) |
104 | : LLScrollListCell(width), | 104 | : LLScrollListCell(width), |
105 | mIcon(icon), | 105 | mIcon(icon), |
106 | // <edit> | ||
107 | mCallback(NULL), | ||
108 | mUserData(NULL), | ||
109 | // </edit> | ||
106 | mColor(LLColor4::white) | 110 | mColor(LLColor4::white) |
107 | { | 111 | { |
108 | } | 112 | } |
@@ -145,6 +149,19 @@ void LLScrollListIcon::setValue(const LLSD& value) | |||
145 | } | 149 | } |
146 | } | 150 | } |
147 | 151 | ||
152 | // <edit> | ||
153 | void LLScrollListIcon::setClickCallback(BOOL (*callback)(void*), void* user_data) | ||
154 | { | ||
155 | mCallback = callback; | ||
156 | mUserData = user_data; | ||
157 | } | ||
158 | |||
159 | BOOL LLScrollListIcon::handleClick() | ||
160 | { | ||
161 | if(mCallback) return mCallback(mUserData); | ||
162 | return FALSE; | ||
163 | } | ||
164 | // </edit> | ||
148 | 165 | ||
149 | void LLScrollListIcon::setColor(const LLColor4& color) | 166 | void LLScrollListIcon::setColor(const LLColor4& color) |
150 | { | 167 | { |
@@ -553,7 +570,7 @@ void LLScrollListItemSeparator::draw(const LLRect& rect, const LLColor4& fg_colo | |||
553 | // LLScrollListCtrl | 570 | // LLScrollListCtrl |
554 | //--------------------------------------------------------------------------- | 571 | //--------------------------------------------------------------------------- |
555 | 572 | ||
556 | LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, | 573 | LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, const LLFontGL* font, |
557 | void (*commit_callback)(LLUICtrl* ctrl, void* userdata), | 574 | void (*commit_callback)(LLUICtrl* ctrl, void* userdata), |
558 | void* callback_user_data, | 575 | void* callback_user_data, |
559 | BOOL allow_multiple_selection, | 576 | BOOL allow_multiple_selection, |
@@ -588,6 +605,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, | |||
588 | mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), | 605 | mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), |
589 | mBorderThickness( 2 ), | 606 | mBorderThickness( 2 ), |
590 | mOnDoubleClickCallback( NULL ), | 607 | mOnDoubleClickCallback( NULL ), |
608 | mOnRightMouseDownCallback( NULL ), | ||
591 | mOnMaximumSelectCallback( NULL ), | 609 | mOnMaximumSelectCallback( NULL ), |
592 | mOnSortChangedCallback( NULL ), | 610 | mOnSortChangedCallback( NULL ), |
593 | mHighlightedItem(-1), | 611 | mHighlightedItem(-1), |
@@ -601,6 +619,15 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, | |||
601 | mOriginalSelection(-1), | 619 | mOriginalSelection(-1), |
602 | mDrewSelected(FALSE) | 620 | mDrewSelected(FALSE) |
603 | { | 621 | { |
622 | if (font) | ||
623 | { | ||
624 | mGLFont = font; | ||
625 | } | ||
626 | else | ||
627 | { | ||
628 | mGLFont = LLFontGL::getFontSansSerifSmall(); | ||
629 | } | ||
630 | |||
604 | mItemListRect.setOriginAndSize( | 631 | mItemListRect.setOriginAndSize( |
605 | mBorderThickness, | 632 | mBorderThickness, |
606 | mBorderThickness, | 633 | mBorderThickness, |
@@ -969,14 +996,14 @@ void LLScrollListCtrl::calcColumnWidths() | |||
969 | column->setWidth(new_width); | 996 | column->setWidth(new_width); |
970 | 997 | ||
971 | // update max content width for this column, by looking at all items | 998 | // update max content width for this column, by looking at all items |
972 | column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; | 999 | column->mMaxContentWidth = column->mHeader ? mGLFont->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0; |
973 | item_list::iterator iter; | 1000 | item_list::iterator iter; |
974 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) | 1001 | for (iter = mItemList.begin(); iter != mItemList.end(); iter++) |
975 | { | 1002 | { |
976 | LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); | 1003 | LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); |
977 | if (!cellp) continue; | 1004 | if (!cellp) continue; |
978 | 1005 | ||
979 | column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); | 1006 | column->mMaxContentWidth = llmax(mGLFont->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); |
980 | } | 1007 | } |
981 | 1008 | ||
982 | max_item_width += column->mMaxContentWidth; | 1009 | max_item_width += column->mMaxContentWidth; |
@@ -1624,7 +1651,7 @@ LLScrollListItem* LLScrollListCtrl::addStringUUIDItem(const std::string& item_te | |||
1624 | if (getItemCount() < mMaxItemCount) | 1651 | if (getItemCount() < mMaxItemCount) |
1625 | { | 1652 | { |
1626 | item = new LLScrollListItem( enabled, NULL, id ); | 1653 | item = new LLScrollListItem( enabled, NULL, id ); |
1627 | item->addColumn(item_text, LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF_SMALL), column_width); | 1654 | item->addColumn(item_text, mGLFont, column_width); |
1628 | addItem( item, pos ); | 1655 | addItem( item, pos ); |
1629 | } | 1656 | } |
1630 | return item; | 1657 | return item; |
@@ -2065,6 +2092,27 @@ BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
2065 | return TRUE; | 2092 | return TRUE; |
2066 | } | 2093 | } |
2067 | 2094 | ||
2095 | BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) | ||
2096 | { | ||
2097 | //BOOL handled = FALSE; | ||
2098 | BOOL handled = handleClick(x, y, mask); | ||
2099 | |||
2100 | if (!handled) | ||
2101 | { | ||
2102 | // Offer the click to the children, even if we aren't enabled | ||
2103 | // so the scroll bars will work. | ||
2104 | if (NULL == LLView::childrenHandleRightMouseDown(x, y, mask)) | ||
2105 | { | ||
2106 | if( mCanSelect && mOnRightMouseDownCallback ) | ||
2107 | { | ||
2108 | mOnRightMouseDownCallback( x, y, mCallbackUserData ); | ||
2109 | } | ||
2110 | } | ||
2111 | } | ||
2112 | |||
2113 | return TRUE; | ||
2114 | } | ||
2115 | |||
2068 | BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) | 2116 | BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) |
2069 | { | 2117 | { |
2070 | // which row was clicked on? | 2118 | // which row was clicked on? |
@@ -2861,6 +2909,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac | |||
2861 | LLScrollListCtrl* scroll_list = new LLScrollListCtrl( | 2909 | LLScrollListCtrl* scroll_list = new LLScrollListCtrl( |
2862 | name, | 2910 | name, |
2863 | rect, | 2911 | rect, |
2912 | NULL, | ||
2864 | callback, | 2913 | callback, |
2865 | NULL, | 2914 | NULL, |
2866 | multi_select, | 2915 | multi_select, |
@@ -3335,7 +3384,11 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
3335 | const LLFontGL *font = LLResMgr::getInstance()->getRes(fontname); | 3384 | const LLFontGL *font = LLResMgr::getInstance()->getRes(fontname); |
3336 | if (!font) | 3385 | if (!font) |
3337 | { | 3386 | { |
3338 | font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ); | 3387 | font = mGLFont; |
3388 | if (!font) | ||
3389 | { | ||
3390 | font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ); | ||
3391 | } | ||
3339 | } | 3392 | } |
3340 | U8 font_style = LLFontGL::getStyleFromString(fontstyle); | 3393 | U8 font_style = LLFontGL::getStyleFromString(fontstyle); |
3341 | 3394 | ||
@@ -3407,7 +3460,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p | |||
3407 | if (new_item->getColumn(column_idx) == NULL) | 3460 | if (new_item->getColumn(column_idx) == NULL) |
3408 | { | 3461 | { |
3409 | LLScrollListColumn* column_ptr = &column_it->second; | 3462 | LLScrollListColumn* column_ptr = &column_it->second; |
3410 | new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->getWidth(), LLFontGL::NORMAL)); | 3463 | new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, mGLFont, column_ptr->getWidth(), LLFontGL::NORMAL)); |
3411 | } | 3464 | } |
3412 | } | 3465 | } |
3413 | 3466 | ||
@@ -3427,7 +3480,7 @@ LLScrollListItem* LLScrollListCtrl::addSimpleElement(const std::string& value, E | |||
3427 | 3480 | ||
3428 | LLScrollListItem *new_item = new LLScrollListItem(entry_id); | 3481 | LLScrollListItem *new_item = new LLScrollListItem(entry_id); |
3429 | 3482 | ||
3430 | const LLFontGL *font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ); | 3483 | const LLFontGL *font = mGLFont; |
3431 | 3484 | ||
3432 | new_item->addColumn(value, font, getRect().getWidth()); | 3485 | new_item->addColumn(value, font, getRect().getWidth()); |
3433 | 3486 | ||
@@ -3614,6 +3667,22 @@ BOOL LLColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
3614 | return TRUE; | 3667 | return TRUE; |
3615 | } | 3668 | } |
3616 | 3669 | ||
3670 | BOOL LLColumnHeader::handleRightMouseDown(S32 x, S32 y, MASK mask) | ||
3671 | { | ||
3672 | if (canResize() && mResizeBar->getRect().pointInRect(x, y)) | ||
3673 | { | ||
3674 | // reshape column to max content width | ||
3675 | LLRect column_rect = getRect(); | ||
3676 | column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth; | ||
3677 | userSetShape(column_rect); | ||
3678 | } | ||
3679 | else | ||
3680 | { | ||
3681 | onClick(this); | ||
3682 | } | ||
3683 | return TRUE; | ||
3684 | } | ||
3685 | |||
3617 | void LLColumnHeader::setImage(const std::string &image_name) | 3686 | void LLColumnHeader::setImage(const std::string &image_name) |
3618 | { | 3687 | { |
3619 | if (mButton) | 3688 | if (mButton) |
diff --git a/linden/indra/llui/llscrolllistctrl.h b/linden/indra/llui/llscrolllistctrl.h index 516e4f1..1b7105f 100644 --- a/linden/indra/llui/llscrolllistctrl.h +++ b/linden/indra/llui/llscrolllistctrl.h | |||
@@ -163,10 +163,18 @@ public: | |||
163 | virtual void setColor(const LLColor4&); | 163 | virtual void setColor(const LLColor4&); |
164 | virtual BOOL isText()const { return FALSE; } | 164 | virtual BOOL isText()const { return FALSE; } |
165 | virtual void setValue(const LLSD& value); | 165 | virtual void setValue(const LLSD& value); |
166 | // <edit> | ||
167 | void setClickCallback(BOOL (*callback)(void*), void* user_data); | ||
168 | virtual BOOL handleClick(); | ||
169 | // </edit> | ||
166 | 170 | ||
167 | private: | 171 | private: |
168 | LLUIImagePtr mIcon; | 172 | LLUIImagePtr mIcon; |
169 | LLColor4 mColor; | 173 | LLColor4 mColor; |
174 | // <edit> | ||
175 | BOOL (*mCallback)(void*); | ||
176 | void* mUserData; | ||
177 | // </edit> | ||
170 | }; | 178 | }; |
171 | 179 | ||
172 | /* | 180 | /* |
@@ -233,6 +241,7 @@ public: | |||
233 | 241 | ||
234 | /*virtual*/ void draw(); | 242 | /*virtual*/ void draw(); |
235 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); | 243 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); |
244 | /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); | ||
236 | 245 | ||
237 | /*virtual*/ void showList(); | 246 | /*virtual*/ void showList(); |
238 | /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding); | 247 | /*virtual*/ LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding); |
@@ -344,6 +353,7 @@ public: | |||
344 | LLScrollListCtrl( | 353 | LLScrollListCtrl( |
345 | const std::string& name, | 354 | const std::string& name, |
346 | const LLRect& rect, | 355 | const LLRect& rect, |
356 | const LLFontGL* font, | ||
347 | void (*commit_callback)(LLUICtrl*, void*), | 357 | void (*commit_callback)(LLUICtrl*, void*), |
348 | void* callback_userdata, | 358 | void* callback_userdata, |
349 | BOOL allow_multiple_selection, | 359 | BOOL allow_multiple_selection, |
@@ -423,6 +433,7 @@ public: | |||
423 | 433 | ||
424 | void highlightNthItem( S32 index ); | 434 | void highlightNthItem( S32 index ); |
425 | void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; } | 435 | void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; } |
436 | void setRightMouseDownCallback( void (*cb)(S32 x, S32 y, void*) ) { mOnRightMouseDownCallback = cb; } | ||
426 | void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; } | 437 | void setMaximumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; } |
427 | void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; } | 438 | void setSortChangedCallback( void (*cb)(void*) ) { mOnSortChangedCallback = cb; } |
428 | 439 | ||
@@ -493,6 +504,9 @@ public: | |||
493 | 504 | ||
494 | virtual S32 getScrollPos() const; | 505 | virtual S32 getScrollPos() const; |
495 | virtual void setScrollPos( S32 pos ); | 506 | virtual void setScrollPos( S32 pos ); |
507 | // <edit> | ||
508 | S32 getPageLines() { return mPageLines; } | ||
509 | // </edit> | ||
496 | S32 getSearchColumn(); | 510 | S32 getSearchColumn(); |
497 | void setSearchColumn(S32 column) { mSearchColumn = column; } | 511 | void setSearchColumn(S32 column) { mSearchColumn = column; } |
498 | S32 getColumnIndexFromOffset(S32 x); | 512 | S32 getColumnIndexFromOffset(S32 x); |
@@ -506,6 +520,7 @@ public: | |||
506 | /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); | 520 | /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); |
507 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); | 521 | /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); |
508 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); | 522 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); |
523 | /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); | ||
509 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); | 524 | /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); |
510 | /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); | 525 | /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); |
511 | /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); | 526 | /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); |
@@ -649,6 +664,7 @@ private: | |||
649 | 664 | ||
650 | S32 mBorderThickness; | 665 | S32 mBorderThickness; |
651 | void (*mOnDoubleClickCallback)(void* userdata); | 666 | void (*mOnDoubleClickCallback)(void* userdata); |
667 | void (*mOnRightMouseDownCallback)(S32 x, S32 y, void* userdata); | ||
652 | void (*mOnMaximumSelectCallback)(void* userdata ); | 668 | void (*mOnMaximumSelectCallback)(void* userdata ); |
653 | void (*mOnSortChangedCallback)(void* userdata); | 669 | void (*mOnSortChangedCallback)(void* userdata); |
654 | 670 | ||
@@ -679,6 +695,8 @@ private: | |||
679 | 695 | ||
680 | // HACK: Did we draw one selected item this frame? | 696 | // HACK: Did we draw one selected item this frame? |
681 | BOOL mDrewSelected; | 697 | BOOL mDrewSelected; |
698 | |||
699 | const LLFontGL* mGLFont; | ||
682 | }; // end class LLScrollListCtrl | 700 | }; // end class LLScrollListCtrl |
683 | 701 | ||
684 | 702 | ||
diff --git a/linden/indra/llui/llsliderctrl.cpp b/linden/indra/llui/llsliderctrl.cpp index 8a13ed4..51d43fb 100644 --- a/linden/indra/llui/llsliderctrl.cpp +++ b/linden/indra/llui/llsliderctrl.cpp | |||
@@ -34,8 +34,6 @@ | |||
34 | 34 | ||
35 | #include "llsliderctrl.h" | 35 | #include "llsliderctrl.h" |
36 | 36 | ||
37 | #include "audioengine.h" | ||
38 | |||
39 | #include "llmath.h" | 37 | #include "llmath.h" |
40 | #include "llfontgl.h" | 38 | #include "llfontgl.h" |
41 | #include "llgl.h" | 39 | #include "llgl.h" |
diff --git a/linden/indra/llui/llspinctrl.cpp b/linden/indra/llui/llspinctrl.cpp index 7eccaca..e66b20e 100644 --- a/linden/indra/llui/llspinctrl.cpp +++ b/linden/indra/llui/llspinctrl.cpp | |||
@@ -45,7 +45,6 @@ | |||
45 | #include "lltextbox.h" | 45 | #include "lltextbox.h" |
46 | #include "llkeyboard.h" | 46 | #include "llkeyboard.h" |
47 | #include "llmath.h" | 47 | #include "llmath.h" |
48 | #include "audioengine.h" | ||
49 | #include "llcontrol.h" | 48 | #include "llcontrol.h" |
50 | #include "llfocusmgr.h" | 49 | #include "llfocusmgr.h" |
51 | #include "llresmgr.h" | 50 | #include "llresmgr.h" |
diff --git a/linden/indra/llui/llstyle.cpp b/linden/indra/llui/llstyle.cpp index a716cbb..61a025e 100644 --- a/linden/indra/llui/llstyle.cpp +++ b/linden/indra/llui/llstyle.cpp | |||
@@ -128,9 +128,13 @@ void LLStyle::setFontName(const std::string& fontname) | |||
128 | { | 128 | { |
129 | mFontID = LLFONT_SMALL; | 129 | mFontID = LLFONT_SMALL; |
130 | } | 130 | } |
131 | else if ((fontname_lc == "sansserifbig")) | 131 | else if ((fontname_lc == "sansserifbigger")) |
132 | { | 132 | { |
133 | mFontID = LLFONT_SANSSERIF_BIG; | 133 | mFontID = LLFONT_SANSSERIF_BIGGER; |
134 | } | ||
135 | else if ((fontname_lc == "sansserifhuge")) | ||
136 | { | ||
137 | mFontID = LLFONT_SANSSERIF_LARGE; | ||
134 | } | 138 | } |
135 | else if (fontname_lc == "small") | 139 | else if (fontname_lc == "small") |
136 | { | 140 | { |
diff --git a/linden/indra/llui/lltexteditor.cpp b/linden/indra/llui/lltexteditor.cpp index 2d46943..5bddcbc 100644 --- a/linden/indra/llui/lltexteditor.cpp +++ b/linden/indra/llui/lltexteditor.cpp | |||
@@ -36,7 +36,6 @@ | |||
36 | 36 | ||
37 | #include "lltexteditor.h" | 37 | #include "lltexteditor.h" |
38 | 38 | ||
39 | #include "llerror.h" | ||
40 | #include "llfontgl.h" | 39 | #include "llfontgl.h" |
41 | #include "llrender.h" | 40 | #include "llrender.h" |
42 | #include "llui.h" | 41 | #include "llui.h" |
@@ -46,7 +45,6 @@ | |||
46 | #include "lltimer.h" | 45 | #include "lltimer.h" |
47 | #include "llmath.h" | 46 | #include "llmath.h" |
48 | 47 | ||
49 | #include "audioengine.h" | ||
50 | #include "llclipboard.h" | 48 | #include "llclipboard.h" |
51 | #include "llscrollbar.h" | 49 | #include "llscrollbar.h" |
52 | #include "llstl.h" | 50 | #include "llstl.h" |
@@ -59,8 +57,15 @@ | |||
59 | #include "llimagegl.h" | 57 | #include "llimagegl.h" |
60 | #include "llwindow.h" | 58 | #include "llwindow.h" |
61 | #include "lltextparser.h" | 59 | #include "lltextparser.h" |
60 | #include "lldir.h" | ||
62 | #include <queue> | 61 | #include <queue> |
63 | #include <stdexcept> | 62 | |
63 | #include "llmenugl.h" | ||
64 | #include <boost/regex.hpp> | ||
65 | #include "../newview/lgghunspell_wrapper.h" | ||
66 | #include "../newview/lltranslate.h" | ||
67 | #include "../newview/llviewercontrol.h" | ||
68 | #include "../newview/lggautocorrect.h" | ||
64 | 69 | ||
65 | // | 70 | // |
66 | // Globals | 71 | // Globals |
@@ -96,7 +101,38 @@ LLColor4 LLTextEditor::mLinkColor = LLColor4::blue; | |||
96 | void (* LLTextEditor::mURLcallback)(const std::string&) = NULL; | 101 | void (* LLTextEditor::mURLcallback)(const std::string&) = NULL; |
97 | bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; | 102 | bool (* LLTextEditor::mSecondlifeURLcallback)(const std::string&) = NULL; |
98 | bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = NULL; | 103 | bool (* LLTextEditor::mSecondlifeURLcallbackRightClick)(const std::string&) = NULL; |
104 | /////////////////////////////////////////////////////////////////// | ||
105 | |||
106 | class TextChatTranslationReceiver : public LLTranslate::TranslationReceiver | ||
107 | { | ||
108 | public : | ||
109 | TextChatTranslationReceiver(const std::string &toLang, LLTextEditor* line, const S32 start, const S32 len): | ||
110 | LLTranslate::TranslationReceiver("", toLang), | ||
111 | m_line(line), | ||
112 | m_position(start), | ||
113 | m_origLength(len) | ||
114 | { | ||
115 | } | ||
99 | 116 | ||
117 | static boost::intrusive_ptr<TextChatTranslationReceiver> build(const std::string &toLang,LLTextEditor* line, const S32 start, const S32 len) | ||
118 | { | ||
119 | return boost::intrusive_ptr<TextChatTranslationReceiver>(new TextChatTranslationReceiver(toLang, line, start, len)); | ||
120 | } | ||
121 | |||
122 | protected: | ||
123 | void handleResponse(const std::string &translation, const std::string &detectedLanguage) | ||
124 | { | ||
125 | m_line->translationReplace(translation, m_position, m_origLength); | ||
126 | } | ||
127 | void handleFailure() | ||
128 | { | ||
129 | LLTranslate::TranslationReceiver::handleFailure(); | ||
130 | } | ||
131 | private: | ||
132 | LLTextEditor* m_line; | ||
133 | S32 m_position; | ||
134 | S32 m_origLength; | ||
135 | }; | ||
100 | 136 | ||
101 | /////////////////////////////////////////////////////////////////// | 137 | /////////////////////////////////////////////////////////////////// |
102 | 138 | ||
@@ -257,6 +293,7 @@ LLTextEditor::LLTextEditor( | |||
257 | LLUICtrl( name, rect, TRUE, NULL, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ), | 293 | LLUICtrl( name, rect, TRUE, NULL, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ), |
258 | mTextIsUpToDate(TRUE), | 294 | mTextIsUpToDate(TRUE), |
259 | mMaxTextByteLength( max_length ), | 295 | mMaxTextByteLength( max_length ), |
296 | mPopupMenuHandle(), | ||
260 | mBaseDocIsPristine(TRUE), | 297 | mBaseDocIsPristine(TRUE), |
261 | mPristineCmd( NULL ), | 298 | mPristineCmd( NULL ), |
262 | mLastCmd( NULL ), | 299 | mLastCmd( NULL ), |
@@ -289,8 +326,12 @@ LLTextEditor::LLTextEditor( | |||
289 | mMouseDownY(0), | 326 | mMouseDownY(0), |
290 | mLastSelectionX(-1), | 327 | mLastSelectionX(-1), |
291 | mLastSelectionY(-1), | 328 | mLastSelectionY(-1), |
329 | mLastContextMenuX(-1), | ||
330 | mLastContextMenuY(-1), | ||
292 | mReflowNeeded(FALSE), | 331 | mReflowNeeded(FALSE), |
293 | mScrollNeeded(FALSE) | 332 | mScrollNeeded(FALSE), |
333 | mSpellCheckable(FALSE), | ||
334 | mAllowTranslate(TRUE) | ||
294 | { | 335 | { |
295 | mSourceID.generate(); | 336 | mSourceID.generate(); |
296 | 337 | ||
@@ -342,8 +383,21 @@ LLTextEditor::LLTextEditor( | |||
342 | 383 | ||
343 | mParseHTML=FALSE; | 384 | mParseHTML=FALSE; |
344 | mHTML.clear(); | 385 | mHTML.clear(); |
345 | } | ||
346 | 386 | ||
387 | // make the popup menu available | ||
388 | |||
389 | LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_rightclick_text.xml",this); | ||
390 | if (!menu) | ||
391 | { | ||
392 | menu = new LLMenuGL(LLStringUtil::null); | ||
393 | } | ||
394 | |||
395 | defineMenuCallbacks(menu); | ||
396 | mPopupMenuHandle = menu->getHandle(); | ||
397 | menu->setBorderColor(gColors.getColor("MenuItemDisabledColor")); | ||
398 | menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor")); | ||
399 | |||
400 | } | ||
347 | 401 | ||
348 | LLTextEditor::~LLTextEditor() | 402 | LLTextEditor::~LLTextEditor() |
349 | { | 403 | { |
@@ -360,8 +414,247 @@ LLTextEditor::~LLTextEditor() | |||
360 | std::for_each(mSegments.begin(), mSegments.end(), DeletePointer()); | 414 | std::for_each(mSegments.begin(), mSegments.end(), DeletePointer()); |
361 | 415 | ||
362 | std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); | 416 | std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); |
417 | LLView::deleteViewByHandle(mPopupMenuHandle); | ||
418 | } | ||
419 | |||
420 | BOOL LLTextEditor::context_enable_cut(void* data) | ||
421 | { | ||
422 | LLTextEditor* line = (LLTextEditor*)data; | ||
423 | return (line && line->canCut()); | ||
424 | } | ||
425 | |||
426 | void LLTextEditor::context_cut(void* data) | ||
427 | { | ||
428 | LLTextEditor* line = (LLTextEditor*)data; | ||
429 | if(line)line->cut(); | ||
430 | } | ||
431 | |||
432 | BOOL LLTextEditor::context_enable_copy(void* data) | ||
433 | { | ||
434 | LLTextEditor* line = (LLTextEditor*)data; | ||
435 | return (line && line->canCopy()); | ||
436 | } | ||
437 | |||
438 | void LLTextEditor::context_copy(void* data) | ||
439 | { | ||
440 | LLTextEditor* line = (LLTextEditor*)data; | ||
441 | if(line)line->copy(); | ||
442 | } | ||
443 | |||
444 | BOOL LLTextEditor::context_enable_translate(void * data) | ||
445 | { | ||
446 | LLTextEditor* editor = (LLTextEditor*)data; | ||
447 | return editor && editor->canTranslate(); | ||
448 | } | ||
449 | |||
450 | void LLTextEditor::context_translate(void * data) | ||
451 | { | ||
452 | LLTextEditor* line = (LLTextEditor*)data; | ||
453 | LLMenuGL* menu = line ? (LLMenuGL*)(line->mPopupMenuHandle.get()) : NULL; | ||
454 | LLMenuGL* translate_menu = menu ? menu->getChildMenuByName("Translation Options", TRUE) : NULL; | ||
455 | if (!translate_menu) | ||
456 | { | ||
457 | return; | ||
458 | } | ||
459 | const std::string to_lang = translate_menu->getHighlightedItem()->getName(); | ||
460 | |||
461 | bool has_text = false; | ||
462 | S32 start, length; | ||
463 | if (line->hasSelection()) | ||
464 | { | ||
465 | // translate selection | ||
466 | start = llmin(line->mSelectionStart, line->mSelectionEnd); | ||
467 | length = abs(line->mSelectionEnd - line->mSelectionStart); | ||
468 | has_text = length > 0; | ||
469 | } | ||
470 | else | ||
471 | { | ||
472 | // translate one word as click position | ||
473 | S32 at = line->getCursorPosFromLocalCoord(line->mLastContextMenuX, line->mLastContextMenuY, TRUE); | ||
474 | has_text = line->getWordBoundriesAt(at, &start, &length); | ||
475 | } | ||
476 | |||
477 | if (has_text) | ||
478 | { | ||
479 | const std::string to_translate = wstring_to_utf8str(line->getWText().substr(start, length)); | ||
480 | LLHTTPClient::ResponderPtr result = TextChatTranslationReceiver::build(to_lang, line, start, length); | ||
481 | LLTranslate::translateMessage(result,"", to_lang, to_translate); | ||
482 | } | ||
483 | } | ||
484 | |||
485 | void LLTextEditor::spell_correct(void* data) | ||
486 | { | ||
487 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | ||
488 | LLTextEditor* line = tempBind->origin; | ||
489 | if(tempBind && line) | ||
490 | { | ||
491 | llinfos << tempBind->menuItem->getName() << " : " << tempBind->origin->getName() << " : " << tempBind->word << llendl; | ||
492 | if(line)line->spellReplace(tempBind); | ||
493 | |||
494 | } | ||
495 | } | ||
496 | void LLTextEditor::spell_show(void * data) | ||
497 | { | ||
498 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | ||
499 | LLTextEditor* line = tempBind->origin; | ||
500 | |||
501 | if (tempBind && line) | ||
502 | { | ||
503 | BOOL show = (tempBind->word == "Show Misspellings"); | ||
504 | glggHunSpell->setSpellCheckHighlight(show); | ||
505 | } | ||
506 | } | ||
507 | |||
508 | void LLTextEditor::getMisspelledWordsPositions(std::vector<S32>& misspell_positions) | ||
509 | { | ||
510 | resetSpellDirty(); | ||
511 | misspell_positions.clear(); | ||
512 | LLWString& text = mWText; | ||
513 | S32 wordStart=0; | ||
514 | S32 wordEnd=spellStart;//start at the scroll start | ||
515 | while(wordEnd < spellEnd) | ||
516 | { | ||
517 | //go through all the chars... XD | ||
518 | if( LLTextEditor::isPartOfWord( text[wordEnd] ) ) | ||
519 | { | ||
520 | // Select word the cursor is over | ||
521 | while ((wordEnd > 0) && LLTextEditor::isPartOfWord(text[wordEnd-1])) | ||
522 | { | ||
523 | wordEnd--; | ||
524 | } | ||
525 | wordStart=wordEnd; | ||
526 | while ((wordEnd < (S32)text.length()) && LLTextEditor::isPartOfWord( text[wordEnd] ) ) | ||
527 | { | ||
528 | wordEnd++; | ||
529 | } | ||
530 | |||
531 | //got a word? -- MC | ||
532 | if (wordStart != wordEnd) | ||
533 | { | ||
534 | std::string regText(text.begin(),text.end()); | ||
535 | std::string selectedWord(regText.substr(wordStart,wordEnd-wordStart)); | ||
536 | |||
537 | if(!selectedWord.empty() && !glggHunSpell->isSpelledRight(selectedWord)) | ||
538 | { | ||
539 | //misspelled word here, and you have just right clicked on it | ||
540 | |||
541 | misspell_positions.push_back(wordStart); | ||
542 | misspell_positions.push_back(wordEnd); | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | wordEnd++; | ||
547 | } | ||
548 | } | ||
549 | |||
550 | void LLTextEditor::spell_add(void* data) | ||
551 | { | ||
552 | SpellMenuBind* tempBind = (SpellMenuBind*)data; | ||
553 | if(tempBind) | ||
554 | { | ||
555 | glggHunSpell->addWordToCustomDictionary(tempBind->word); | ||
556 | tempBind->origin->mPrevSpelledText.erase();//make it update | ||
557 | } | ||
558 | } | ||
559 | |||
560 | BOOL LLTextEditor::context_enable_paste(void* data) | ||
561 | { | ||
562 | LLTextEditor* line = (LLTextEditor*)data; | ||
563 | return(line && line->canPaste()); | ||
564 | } | ||
565 | |||
566 | void LLTextEditor::context_paste(void* data) | ||
567 | { | ||
568 | LLTextEditor* line = (LLTextEditor*)data; | ||
569 | if(line)line->paste(); | ||
570 | } | ||
571 | |||
572 | BOOL LLTextEditor::context_enable_delete(void* data) | ||
573 | { | ||
574 | LLTextEditor* line = (LLTextEditor*)data; | ||
575 | return (line && line->canDoDelete()); | ||
576 | } | ||
577 | |||
578 | void LLTextEditor::context_delete(void* data) | ||
579 | { | ||
580 | LLTextEditor* line = (LLTextEditor*)data; | ||
581 | if(line)line->doDelete(); | ||
582 | } | ||
583 | |||
584 | BOOL LLTextEditor::context_enable_selectall(void* data) | ||
585 | { | ||
586 | LLTextEditor* line = (LLTextEditor*)data; | ||
587 | return (line && line->canSelectAll()); | ||
588 | } | ||
589 | |||
590 | void LLTextEditor::context_selectall(void* data) | ||
591 | { | ||
592 | LLTextEditor* line = (LLTextEditor*)data; | ||
593 | if(line)line->selectAll(); | ||
594 | } | ||
595 | |||
596 | // method to define the associated callbacks | ||
597 | void LLTextEditor::defineMenuCallbacks(LLMenuGL* menu) { | ||
598 | |||
599 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
600 | "Cut Text", | ||
601 | this, | ||
602 | (void*)context_enable_cut); | ||
603 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
604 | "Cut Text", | ||
605 | this, | ||
606 | (void*)context_cut); | ||
607 | |||
608 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
609 | "Copy Text", | ||
610 | this, | ||
611 | (void*)context_enable_copy); | ||
612 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
613 | "Copy Text", | ||
614 | this, | ||
615 | (void*)context_copy); | ||
616 | |||
617 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
618 | "Paste Text", | ||
619 | this, | ||
620 | (void*)context_enable_paste); | ||
621 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
622 | "Paste Text", | ||
623 | this, | ||
624 | (void*)context_paste); | ||
625 | |||
626 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
627 | "Delete Text", | ||
628 | this, | ||
629 | (void*)context_enable_delete); | ||
630 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
631 | "Delete Text", | ||
632 | this, | ||
633 | (void*)context_delete); | ||
634 | |||
635 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
636 | "Select All Text", | ||
637 | this, | ||
638 | (void*)context_enable_selectall); | ||
639 | menu->setCtrlResponse(1+LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_CLICK, | ||
640 | "Select All Text", | ||
641 | this, | ||
642 | (void*)context_selectall); | ||
643 | |||
644 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_ON_ENABLE, | ||
645 | "Translate Text", | ||
646 | this, | ||
647 | (void*)context_enable_translate); | ||
648 | menu->setCtrlResponse(LLCallbackInformation::LL_MENU_ITEM_CALL_GL_TRANSLATE, | ||
649 | "Translate Text", | ||
650 | this, | ||
651 | (void*)context_translate); | ||
652 | |||
653 | |||
654 | |||
363 | } | 655 | } |
364 | 656 | ||
657 | |||
365 | void LLTextEditor::setTrackColor( const LLColor4& color ) | 658 | void LLTextEditor::setTrackColor( const LLColor4& color ) |
366 | { | 659 | { |
367 | mScrollbar->setTrackColor(color); | 660 | mScrollbar->setTrackColor(color); |
@@ -738,6 +1031,26 @@ S32 LLTextEditor::nextWordPos(S32 cursorPos) const | |||
738 | return cursorPos; | 1031 | return cursorPos; |
739 | } | 1032 | } |
740 | 1033 | ||
1034 | BOOL LLTextEditor::getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const | ||
1035 | { | ||
1036 | S32 pos = at; | ||
1037 | if (isPartOfWord(mWText[pos])) | ||
1038 | { | ||
1039 | while ( (pos > 0) && isPartOfWord(mWText[pos - 1]) ) | ||
1040 | { | ||
1041 | pos--; | ||
1042 | } | ||
1043 | *word_begin = pos; | ||
1044 | while ( (pos < getLength()) && isPartOfWord(mWText[pos]) ) | ||
1045 | { | ||
1046 | pos++; | ||
1047 | } | ||
1048 | *word_length = pos - *word_begin; | ||
1049 | return TRUE; | ||
1050 | } | ||
1051 | return FALSE; | ||
1052 | } | ||
1053 | |||
741 | S32 LLTextEditor::getLineStart( S32 line ) const | 1054 | S32 LLTextEditor::getLineStart( S32 line ) const |
742 | { | 1055 | { |
743 | S32 num_lines = getLineCount(); | 1056 | S32 num_lines = getLineCount(); |
@@ -1142,6 +1455,14 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) | |||
1142 | { | 1455 | { |
1143 | BOOL handled = FALSE; | 1456 | BOOL handled = FALSE; |
1144 | 1457 | ||
1458 | // SL-51858: Key presses are not being passed to the Popup menu. | ||
1459 | // A proper fix is non-trivial so instead just close the menu. | ||
1460 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | ||
1461 | if (menu && menu->isOpen()) | ||
1462 | { | ||
1463 | LLMenuGL::sMenuContainer->hideMenus(); | ||
1464 | } | ||
1465 | |||
1145 | // Let scrollbar have first dibs | 1466 | // Let scrollbar have first dibs |
1146 | handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; | 1467 | handled = LLView::childrenHandleMouseDown(x, y, mask) != NULL; |
1147 | 1468 | ||
@@ -1216,6 +1537,99 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) | |||
1216 | 1537 | ||
1217 | return handled; | 1538 | return handled; |
1218 | } | 1539 | } |
1540 | BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask ) | ||
1541 | { | ||
1542 | setFocus(TRUE); | ||
1543 | |||
1544 | //setCursorAtLocalPos( x, y, TRUE ); | ||
1545 | S32 wordStart = 0; | ||
1546 | S32 wordLen = 0; | ||
1547 | S32 pos = getCursorPosFromLocalCoord(x,y,TRUE); | ||
1548 | |||
1549 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | ||
1550 | if (menu) | ||
1551 | { | ||
1552 | for(int i = 0;i<(int)suggestionMenuItems.size();i++) | ||
1553 | { | ||
1554 | SpellMenuBind * tempBind = suggestionMenuItems[i]; | ||
1555 | if(tempBind) | ||
1556 | { | ||
1557 | menu->remove(tempBind->menuItem); | ||
1558 | tempBind->menuItem->die(); | ||
1559 | //delete tempBind->menuItem; | ||
1560 | //tempBind->menuItem = NULL; | ||
1561 | delete tempBind; | ||
1562 | } | ||
1563 | } | ||
1564 | suggestionMenuItems.clear(); | ||
1565 | |||
1566 | // spell_check="true" in xui | ||
1567 | menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable); | ||
1568 | if (!mReadOnly && mSpellCheckable) | ||
1569 | { | ||
1570 | bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen); | ||
1571 | if (is_word_part) | ||
1572 | { | ||
1573 | const LLWString &text = mWText; | ||
1574 | std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen)); | ||
1575 | |||
1576 | if (!glggHunSpell->isSpelledRight(selectedWord)) | ||
1577 | { | ||
1578 | //misspelled word here, and you have just right clicked on it! | ||
1579 | std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord); | ||
1580 | |||
1581 | for (int i = 0; i<(int)suggs.size(); i++) | ||
1582 | { | ||
1583 | SpellMenuBind * tempStruct = new SpellMenuBind; | ||
1584 | tempStruct->origin = this; | ||
1585 | tempStruct->word = suggs[i]; | ||
1586 | tempStruct->wordPositionEnd = wordStart + wordLen; | ||
1587 | tempStruct->wordPositionStart=wordStart; | ||
1588 | tempStruct->wordY=y; | ||
1589 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | ||
1590 | tempStruct->word, spell_correct, NULL, tempStruct); | ||
1591 | tempStruct->menuItem = suggMenuItem; | ||
1592 | suggestionMenuItems.push_back(tempStruct); | ||
1593 | menu->append(suggMenuItem); | ||
1594 | } | ||
1595 | SpellMenuBind * tempStruct = new SpellMenuBind; | ||
1596 | tempStruct->origin = this; | ||
1597 | tempStruct->word = selectedWord; | ||
1598 | tempStruct->wordPositionEnd = wordStart + wordLen; | ||
1599 | tempStruct->wordPositionStart=wordStart; | ||
1600 | tempStruct->wordY=y; | ||
1601 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | ||
1602 | "Add Word", spell_add, NULL, tempStruct); | ||
1603 | tempStruct->menuItem = suggMenuItem; | ||
1604 | suggestionMenuItems.push_back(tempStruct); | ||
1605 | menu->append(suggMenuItem); | ||
1606 | } | ||
1607 | } | ||
1608 | |||
1609 | SpellMenuBind * tempStruct = new SpellMenuBind; | ||
1610 | tempStruct->origin = this; | ||
1611 | if (glggHunSpell->getSpellCheckHighlight()) | ||
1612 | { | ||
1613 | tempStruct->word = "Hide Misspellings"; | ||
1614 | } | ||
1615 | else | ||
1616 | { | ||
1617 | tempStruct->word = "Show Misspellings"; | ||
1618 | } | ||
1619 | LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL( | ||
1620 | tempStruct->word, spell_show, NULL, tempStruct); | ||
1621 | tempStruct->menuItem = suggMenuItem; | ||
1622 | suggestionMenuItems.push_back(tempStruct); | ||
1623 | menu->append(suggMenuItem); | ||
1624 | } | ||
1625 | mLastContextMenuX = x; | ||
1626 | mLastContextMenuY = y; | ||
1627 | menu->buildDrawLabels(); | ||
1628 | menu->updateParent(LLMenuGL::sMenuContainer); | ||
1629 | LLMenuGL::showPopup(this, menu, x, y); | ||
1630 | } | ||
1631 | return TRUE; | ||
1632 | } | ||
1219 | 1633 | ||
1220 | 1634 | ||
1221 | BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) | 1635 | BOOL LLTextEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask) |
@@ -1350,11 +1764,6 @@ BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask) | |||
1350 | 1764 | ||
1351 | setCursorAtLocalPos( x, y, TRUE ); | 1765 | setCursorAtLocalPos( x, y, TRUE ); |
1352 | endSelection(); | 1766 | endSelection(); |
1353 | |||
1354 | updateScrollFromCursor(); | ||
1355 | |||
1356 | // take selection to primary clipboard | ||
1357 | updatePrimary(); | ||
1358 | } | 1767 | } |
1359 | 1768 | ||
1360 | if( !hasSelection() ) | 1769 | if( !hasSelection() ) |
@@ -1432,7 +1841,6 @@ BOOL LLTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask) | |||
1432 | 1841 | ||
1433 | handled = TRUE; | 1842 | handled = TRUE; |
1434 | } | 1843 | } |
1435 | |||
1436 | return handled; | 1844 | return handled; |
1437 | } | 1845 | } |
1438 | 1846 | ||
@@ -1913,6 +2321,45 @@ BOOL LLTextEditor::canPaste() const | |||
1913 | return !mReadOnly && gClipboard.canPasteString(); | 2321 | return !mReadOnly && gClipboard.canPasteString(); |
1914 | } | 2322 | } |
1915 | 2323 | ||
2324 | void LLTextEditor::spellReplace(SpellMenuBind* spellData) | ||
2325 | { | ||
2326 | remove( spellData->wordPositionStart, | ||
2327 | spellData->wordPositionEnd - spellData->wordPositionStart, TRUE ); | ||
2328 | LLWString clean_string = utf8str_to_wstring(spellData->word); | ||
2329 | insert(spellData->wordPositionStart, clean_string, FALSE); | ||
2330 | mCursorPos+=clean_string.length() - (spellData->wordPositionEnd-spellData->wordPositionStart); | ||
2331 | needsReflow(); | ||
2332 | } | ||
2333 | |||
2334 | void LLTextEditor::translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length) | ||
2335 | { | ||
2336 | //*TODO: should probably check if the content was modified since the http query | ||
2337 | // was made, so we don't insert text in the wrong place. | ||
2338 | BOOL replace = gSavedSettings.getBOOL("EmeraldTranslateReplace"); | ||
2339 | LLWString wtext = utf8str_to_wstring(replace ? translation : " (" + translation + ")"); | ||
2340 | S32 pos = replace ? orig_start : orig_start + orig_length; | ||
2341 | if (replace) | ||
2342 | { | ||
2343 | remove(orig_start, orig_length, FALSE); | ||
2344 | } | ||
2345 | S32 inserted = insert(pos, wtext, FALSE); | ||
2346 | if (hasSelection()) | ||
2347 | { | ||
2348 | mSelectionStart = llclamp(pos, 0, getLength()); | ||
2349 | mSelectionEnd = llclamp(pos + inserted, mSelectionStart, getLength()); | ||
2350 | } | ||
2351 | setCursorPos(pos + inserted); | ||
2352 | needsReflow(); | ||
2353 | } | ||
2354 | |||
2355 | BOOL LLTextEditor::canTranslate() const | ||
2356 | { | ||
2357 | // if allow_translate="true" in xui, and if other factors permit, we allow it | ||
2358 | S32 pos = getCursorPosFromLocalCoord(mLastContextMenuX, mLastContextMenuY, TRUE); | ||
2359 | bool is_word_part = (pos > -1) && isPartOfWord(mWText[pos]); | ||
2360 | return (mAllowTranslate && !mReadOnly && (is_word_part || hasSelection())); | ||
2361 | } | ||
2362 | |||
1916 | // paste from clipboard | 2363 | // paste from clipboard |
1917 | void LLTextEditor::paste() | 2364 | void LLTextEditor::paste() |
1918 | { | 2365 | { |
@@ -1932,25 +2379,35 @@ void LLTextEditor::pasteHelper(bool is_primary) | |||
1932 | { | 2379 | { |
1933 | bool can_paste_it; | 2380 | bool can_paste_it; |
1934 | if (is_primary) | 2381 | if (is_primary) |
2382 | { | ||
1935 | can_paste_it = canPastePrimary(); | 2383 | can_paste_it = canPastePrimary(); |
2384 | } | ||
1936 | else | 2385 | else |
2386 | { | ||
1937 | can_paste_it = canPaste(); | 2387 | can_paste_it = canPaste(); |
2388 | } | ||
1938 | 2389 | ||
1939 | if (!can_paste_it) | 2390 | if (!can_paste_it) |
1940 | { | 2391 | { |
1941 | return; | 2392 | return; |
1942 | } | 2393 | } |
2394 | |||
1943 | LLUUID source_id; | 2395 | LLUUID source_id; |
1944 | LLWString paste; | 2396 | LLWString paste; |
1945 | if (is_primary) | 2397 | if (is_primary) |
2398 | { | ||
1946 | paste = gClipboard.getPastePrimaryWString(&source_id); | 2399 | paste = gClipboard.getPastePrimaryWString(&source_id); |
2400 | } | ||
1947 | else | 2401 | else |
2402 | { | ||
1948 | paste = gClipboard.getPasteWString(&source_id); | 2403 | paste = gClipboard.getPasteWString(&source_id); |
2404 | } | ||
1949 | 2405 | ||
1950 | if (paste.empty()) | 2406 | if (paste.empty()) |
1951 | { | 2407 | { |
1952 | return; | 2408 | return; |
1953 | } | 2409 | } |
2410 | |||
1954 | // Delete any selected characters (the paste replaces them) | 2411 | // Delete any selected characters (the paste replaces them) |
1955 | if( (!is_primary) && hasSelection() ) | 2412 | if( (!is_primary) && hasSelection() ) |
1956 | { | 2413 | { |
@@ -1995,7 +2452,7 @@ void LLTextEditor::copyPrimary() | |||
1995 | return; | 2452 | return; |
1996 | } | 2453 | } |
1997 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); | 2454 | S32 left_pos = llmin( mSelectionStart, mSelectionEnd ); |
1998 | S32 length = abs( mSelectionStart - mSelectionEnd ); | 2455 | S32 length = llabs( mSelectionStart - mSelectionEnd ); |
1999 | gClipboard.copyFromPrimarySubstring(mWText, left_pos, length, mSourceID); | 2456 | gClipboard.copyFromPrimarySubstring(mWText, left_pos, length, mSourceID); |
2000 | } | 2457 | } |
2001 | 2458 | ||
@@ -2262,6 +2719,13 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask ) | |||
2262 | BOOL selection_modified = FALSE; | 2719 | BOOL selection_modified = FALSE; |
2263 | BOOL return_key_hit = FALSE; | 2720 | BOOL return_key_hit = FALSE; |
2264 | BOOL text_may_have_changed = TRUE; | 2721 | BOOL text_may_have_changed = TRUE; |
2722 | // SL-51858: Key presses are not being passed to the Popup menu. | ||
2723 | // A proper fix is non-trivial so instead just close the menu. | ||
2724 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | ||
2725 | if (menu && menu->isOpen()) | ||
2726 | { | ||
2727 | LLMenuGL::sMenuContainer->hideMenus(); | ||
2728 | } | ||
2265 | 2729 | ||
2266 | if ( gFocusMgr.getKeyboardFocus() == this ) | 2730 | if ( gFocusMgr.getKeyboardFocus() == this ) |
2267 | { | 2731 | { |
@@ -2306,6 +2770,14 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask ) | |||
2306 | } | 2770 | } |
2307 | } | 2771 | } |
2308 | 2772 | ||
2773 | // SL-51858: Key presses are not being passed to the Popup menu. | ||
2774 | // A proper fix is non-trivial so instead just close the menu. | ||
2775 | LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); | ||
2776 | if (menu && menu->isOpen()) | ||
2777 | { | ||
2778 | LLMenuGL::sMenuContainer->hideMenus(); | ||
2779 | } | ||
2780 | |||
2309 | // Handle most keys only if the text editor is writeable. | 2781 | // Handle most keys only if the text editor is writeable. |
2310 | if( !mReadOnly ) | 2782 | if( !mReadOnly ) |
2311 | { | 2783 | { |
@@ -2740,10 +3212,155 @@ void LLTextEditor::drawSelectionBackground() | |||
2740 | } | 3212 | } |
2741 | } | 3213 | } |
2742 | 3214 | ||
3215 | void LLTextEditor::autoCorrectText() | ||
3216 | { | ||
3217 | static BOOL *doAnything = rebind_llcontrol<BOOL>("EmeraldEnableAutoCorrect", &gSavedSettings, true); | ||
3218 | if (!mReadOnly && *doAnything && isSpellDirty()) | ||
3219 | { | ||
3220 | S32 wordStart = 0; | ||
3221 | S32 wordEnd = mCursorPos-1; | ||
3222 | if (wordEnd < 1) | ||
3223 | { | ||
3224 | return; | ||
3225 | } | ||
3226 | LLWString& text = mWText; | ||
3227 | if (text.size() < 1 || LLTextEditor::isPartOfWord(text[wordEnd])) | ||
3228 | { | ||
3229 | return;//we only check on word breaks | ||
3230 | } | ||
3231 | |||
3232 | wordEnd--; | ||
3233 | if (LLTextEditor::isPartOfWord(text[wordEnd])) | ||
3234 | { | ||
3235 | while ((wordEnd > 0) && (text[wordEnd-1]!=' ')) | ||
3236 | { | ||
3237 | wordEnd--; | ||
3238 | } | ||
3239 | wordStart = wordEnd; | ||
3240 | while ((wordEnd < (S32)text.length()) && (' '!= text[wordEnd] ) ) | ||
3241 | { | ||
3242 | wordEnd++; | ||
3243 | } | ||
3244 | std::string lastTypedWord(std::string(text.begin(), | ||
3245 | text.end()).substr(wordStart, wordEnd-wordStart)); | ||
3246 | |||
3247 | std::string regText(text.begin(), text.end()); | ||
3248 | |||
3249 | std::string correctedWord(LGGAutoCorrect::getInstance()->replaceWord(lastTypedWord)); | ||
3250 | if (correctedWord != lastTypedWord) | ||
3251 | { | ||
3252 | int dif = correctedWord.length() - lastTypedWord.length(); | ||
3253 | regText.replace(wordStart, lastTypedWord.length(), correctedWord); | ||
3254 | mWText = utf8str_to_wstring(regText); | ||
3255 | mCursorPos += dif; | ||
3256 | needsReflow(); | ||
3257 | } | ||
3258 | } | ||
3259 | } | ||
3260 | } | ||
3261 | |||
3262 | void LLTextEditor::drawMisspelled() | ||
3263 | { | ||
3264 | if (!mReadOnly && mSpellCheckable) | ||
3265 | { | ||
3266 | if( | ||
3267 | ( ((getLength()<400)||(false)) &&( (S32(mSpellTimer.getElapsedTimeF32() / 1) & 1) )) | ||
3268 | || | ||
3269 | (S32(mKeystrokeTimer.getElapsedTimeF32() / 1) & 1) | ||
3270 | ) | ||
3271 | { | ||
3272 | S32 newSpellStart = getLineStart(mScrollbar->getDocPos());//start at the scroll start | ||
3273 | S32 newSpellEnd = getLineStart(mScrollbar->getDocPos() + 1 + mScrollbar->getDocSize()-mScrollbar->getDocPosMax());//end at the end o.o | ||
3274 | |||
3275 | if (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()) | ||
3276 | { | ||
3277 | newSpellEnd = (S32)mWText.length(); | ||
3278 | } | ||
3279 | if (isSpellDirty() || (newSpellEnd!=spellEnd || newSpellStart!=spellStart)) | ||
3280 | { | ||
3281 | spellEnd = newSpellEnd; | ||
3282 | spellStart = newSpellStart; | ||
3283 | getMisspelledWordsPositions(mMisspellLocations); | ||
3284 | } | ||
3285 | } | ||
3286 | //draw | ||
3287 | if (!mMisspellLocations.empty() && glggHunSpell->getSpellCheckHighlight()) | ||
3288 | { | ||
3289 | for (int i = 0; i<(int)mMisspellLocations.size() ;i++) | ||
3290 | { | ||
3291 | S32 wstart = mMisspellLocations[i]; | ||
3292 | S32 wend = mMisspellLocations[++i]; | ||
3293 | //start curor code mod | ||
3294 | const LLWString &text = mWText; | ||
3295 | const S32 text_len = getLength(); | ||
3296 | // Skip through the lines we aren't drawing. | ||
3297 | S32 search_pos = mScrollbar->getDocPos(); | ||
3298 | S32 num_lines = getLineCount(); | ||
3299 | if (search_pos >= num_lines) | ||
3300 | { | ||
3301 | return; | ||
3302 | } | ||
3303 | S32 line_start = getLineStart(search_pos); | ||
3304 | F32 line_height = mGLFont->getLineHeight(); | ||
3305 | F32 text_y = (F32)(mTextRect.mTop) - line_height; | ||
3306 | |||
3307 | F32 word_left = 0.f; | ||
3308 | F32 word_right = 0.f; | ||
3309 | F32 word_bottom = 0.f; | ||
3310 | BOOL word_visible = FALSE; | ||
3311 | |||
3312 | S32 line_end = 0; | ||
3313 | // Determine if the cursor is visible and if so what its coordinates are. | ||
3314 | while( (mTextRect.mBottom <= llround(text_y)) && (search_pos < num_lines)) | ||
3315 | { | ||
3316 | line_end = text_len + 1; | ||
3317 | S32 next_line = -1; | ||
3318 | |||
3319 | if ((search_pos + 1) < num_lines) | ||
3320 | { | ||
3321 | next_line = getLineStart(search_pos + 1); | ||
3322 | line_end = next_line - 1; | ||
3323 | } | ||
3324 | const llwchar* line = text.c_str() + line_start; | ||
3325 | // Find the cursor and selection bounds | ||
3326 | if( line_start <= wstart && wend <= line_end ) | ||
3327 | { | ||
3328 | word_visible = TRUE; | ||
3329 | word_left = (F32)mTextRect.mLeft + mGLFont->getWidthF32(line, 0, wstart - line_start, mAllowEmbeddedItems )-1.f; | ||
3330 | word_right = (F32)mTextRect.mLeft + mGLFont->getWidthF32(line, 0, wend - line_start, mAllowEmbeddedItems )+1.f; | ||
3331 | word_bottom = text_y; | ||
3332 | break; | ||
3333 | } | ||
3334 | // move down one line | ||
3335 | text_y -= line_height; | ||
3336 | line_start = next_line; | ||
3337 | search_pos++; | ||
3338 | } | ||
3339 | if (mShowLineNumbers) | ||
3340 | { | ||
3341 | word_left += UI_TEXTEDITOR_LINE_NUMBER_MARGIN; | ||
3342 | word_right += UI_TEXTEDITOR_LINE_NUMBER_MARGIN; | ||
3343 | } | ||
3344 | // Draw the cursor | ||
3345 | if (word_visible) | ||
3346 | { | ||
3347 | //end cursor code mod | ||
3348 | gGL.color4ub(255,0,0,200); | ||
3349 | while (word_left<word_right) | ||
3350 | { | ||
3351 | gl_line_2d(word_left,word_bottom-2, word_left+3,word_bottom+1); | ||
3352 | gl_line_2d(word_left+3,word_bottom+1, word_left+6,word_bottom-2); | ||
3353 | word_left += 6; | ||
3354 | } | ||
3355 | } | ||
3356 | } | ||
3357 | } | ||
3358 | } | ||
3359 | } | ||
3360 | |||
2743 | void LLTextEditor::drawCursor() | 3361 | void LLTextEditor::drawCursor() |
2744 | { | 3362 | { |
2745 | if( gFocusMgr.getKeyboardFocus() == this | 3363 | if (!mReadOnly && gFocusMgr.getKeyboardFocus() == this && gShowTextEditCursor) |
2746 | && gShowTextEditCursor && !mReadOnly) | ||
2747 | { | 3364 | { |
2748 | const LLWString &text = mWText; | 3365 | const LLWString &text = mWText; |
2749 | const S32 text_len = getLength(); | 3366 | const S32 text_len = getLength(); |
@@ -3205,6 +3822,8 @@ void LLTextEditor::draw() | |||
3205 | mReflowNeeded = FALSE; | 3822 | mReflowNeeded = FALSE; |
3206 | } | 3823 | } |
3207 | 3824 | ||
3825 | autoCorrectText(); | ||
3826 | |||
3208 | // then update scroll position, as cursor may have moved | 3827 | // then update scroll position, as cursor may have moved |
3209 | if (mScrollNeeded) | 3828 | if (mScrollNeeded) |
3210 | { | 3829 | { |
@@ -3222,7 +3841,8 @@ void LLTextEditor::draw() | |||
3222 | drawPreeditMarker(); | 3841 | drawPreeditMarker(); |
3223 | drawText(); | 3842 | drawText(); |
3224 | drawCursor(); | 3843 | drawCursor(); |
3225 | 3844 | drawMisspelled(); | |
3845 | resetSpellDirty(); | ||
3226 | unbindEmbeddedChars(mGLFont); | 3846 | unbindEmbeddedChars(mGLFont); |
3227 | 3847 | ||
3228 | //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret | 3848 | //RN: the decision was made to always show the orange border for keyboard focus but do not put an insertion caret |
@@ -3250,6 +3870,8 @@ void LLTextEditor::onTabInto() | |||
3250 | void LLTextEditor::clear() | 3870 | void LLTextEditor::clear() |
3251 | { | 3871 | { |
3252 | setText(LLStringUtil::null); | 3872 | setText(LLStringUtil::null); |
3873 | std::for_each(mSegments.begin(), mSegments.end(), DeletePointer()); | ||
3874 | mSegments.clear(); | ||
3253 | } | 3875 | } |
3254 | 3876 | ||
3255 | // Start or stop the editor from accepting text-editing keystrokes | 3877 | // Start or stop the editor from accepting text-editing keystrokes |
@@ -3598,13 +4220,13 @@ void LLTextEditor::autoIndent() | |||
3598 | } | 4220 | } |
3599 | 4221 | ||
3600 | // Inserts new text at the cursor position | 4222 | // Inserts new text at the cursor position |
3601 | void LLTextEditor::insertText(const std::string &new_text) | 4223 | void LLTextEditor::insertText(const std::string &new_text,BOOL deleteCurrentSelection) |
3602 | { | 4224 | { |
3603 | BOOL enabled = getEnabled(); | 4225 | BOOL enabled = getEnabled(); |
3604 | setEnabled( TRUE ); | 4226 | setEnabled( TRUE ); |
3605 | 4227 | ||
3606 | // Delete any selected characters (the insertion replaces them) | 4228 | // Delete any selected characters (the insertion replaces them) |
3607 | if( hasSelection() ) | 4229 | if( hasSelection() && (deleteCurrentSelection)) |
3608 | { | 4230 | { |
3609 | deleteSelection(TRUE); | 4231 | deleteSelection(TRUE); |
3610 | } | 4232 | } |
@@ -3624,7 +4246,10 @@ void LLTextEditor::appendColoredText(const std::string &new_text, | |||
3624 | const std::string& font_name) | 4246 | const std::string& font_name) |
3625 | { | 4247 | { |
3626 | LLColor4 lcolor=color; | 4248 | LLColor4 lcolor=color; |
3627 | if (mParseHighlights) | 4249 | // If LindenUserDir is empty then we didn't login yet. |
4250 | // In that case we can't instantiate LLTextParser, which | ||
4251 | // is initialized per user. | ||
4252 | if (mParseHighlights && !gDirUtilp->getLindenUserDir(true).empty()) | ||
3628 | { | 4253 | { |
3629 | LLTextParser* highlight = LLTextParser::getInstance(); | 4254 | LLTextParser* highlight = LLTextParser::getInstance(); |
3630 | highlight->parseFullLineHighlights(new_text, &lcolor); | 4255 | highlight->parseFullLineHighlights(new_text, &lcolor); |
@@ -3638,9 +4263,9 @@ void LLTextEditor::appendColoredText(const std::string &new_text, | |||
3638 | } | 4263 | } |
3639 | 4264 | ||
3640 | void LLTextEditor::appendStyledText(const std::string &new_text, | 4265 | void LLTextEditor::appendStyledText(const std::string &new_text, |
3641 | bool allow_undo, | 4266 | bool allow_undo, |
3642 | bool prepend_newline, | 4267 | bool prepend_newline, |
3643 | const LLStyleSP stylep) | 4268 | LLStyleSP stylep) |
3644 | { | 4269 | { |
3645 | S32 part = (S32)LLTextParser::WHOLE; | 4270 | S32 part = (S32)LLTextParser::WHOLE; |
3646 | if(mParseHTML) | 4271 | if(mParseHTML) |
@@ -3648,9 +4273,9 @@ void LLTextEditor::appendStyledText(const std::string &new_text, | |||
3648 | 4273 | ||
3649 | S32 start=0,end=0; | 4274 | S32 start=0,end=0; |
3650 | std::string text = new_text; | 4275 | std::string text = new_text; |
3651 | while ( findHTML(text, &start, &end) ) | 4276 | std::string url; |
4277 | while ( findHTML(text, &start, &end, url) ) | ||
3652 | { | 4278 | { |
3653 | |||
3654 | LLStyleSP html(new LLStyle); | 4279 | LLStyleSP html(new LLStyle); |
3655 | html->setVisible(true); | 4280 | html->setVisible(true); |
3656 | html->setColor(mLinkColor); | 4281 | html->setColor(mLinkColor); |
@@ -3675,9 +4300,9 @@ void LLTextEditor::appendStyledText(const std::string &new_text, | |||
3675 | appendHighlightedText(subtext,allow_undo, prepend_newline, part, stylep); | 4300 | appendHighlightedText(subtext,allow_undo, prepend_newline, part, stylep); |
3676 | } | 4301 | } |
3677 | 4302 | ||
3678 | html->setLinkHREF(text.substr(start,end-start)); | 4303 | html->setLinkHREF(url); |
3679 | appendText(text.substr(start, end-start),allow_undo, prepend_newline, html); | 4304 | appendText(text.substr(start, end-start),allow_undo, prepend_newline, html); |
3680 | if (end < (S32)text.length()) | 4305 | if (end < (S32)text.length()) |
3681 | { | 4306 | { |
3682 | text = text.substr(end,text.length() - end); | 4307 | text = text.substr(end,text.length() - end); |
3683 | end=0; | 4308 | end=0; |
@@ -3688,6 +4313,7 @@ void LLTextEditor::appendStyledText(const std::string &new_text, | |||
3688 | break; | 4313 | break; |
3689 | } | 4314 | } |
3690 | } | 4315 | } |
4316 | |||
3691 | if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END; | 4317 | if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END; |
3692 | if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, stylep); | 4318 | if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, stylep); |
3693 | } | 4319 | } |
@@ -3703,7 +4329,10 @@ void LLTextEditor::appendHighlightedText(const std::string &new_text, | |||
3703 | S32 highlight_part, | 4329 | S32 highlight_part, |
3704 | LLStyleSP stylep) | 4330 | LLStyleSP stylep) |
3705 | { | 4331 | { |
3706 | if (mParseHighlights) | 4332 | // If LindenUserDir is empty then we didn't login yet. |
4333 | // In that case we can't instantiate LLTextParser, which | ||
4334 | // is initialized per user. | ||
4335 | if (mParseHighlights && !gDirUtilp->getLindenUserDir(true).empty()) | ||
3707 | { | 4336 | { |
3708 | LLTextParser* highlight = LLTextParser::getInstance(); | 4337 | LLTextParser* highlight = LLTextParser::getInstance(); |
3709 | 4338 | ||
@@ -3784,6 +4413,10 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool | |||
3784 | { | 4413 | { |
3785 | mSelectionStart = selection_start; | 4414 | mSelectionStart = selection_start; |
3786 | mSelectionEnd = selection_end; | 4415 | mSelectionEnd = selection_end; |
4416 | |||
4417 | |||
4418 | |||
4419 | |||
3787 | mIsSelecting = was_selecting; | 4420 | mIsSelecting = was_selecting; |
3788 | setCursorPos(cursor_pos); | 4421 | setCursorPos(cursor_pos); |
3789 | } | 4422 | } |
@@ -3952,6 +4585,15 @@ void LLTextEditor::loadKeywords(const std::string& filename, | |||
3952 | } | 4585 | } |
3953 | } | 4586 | } |
3954 | 4587 | ||
4588 | void LLTextEditor::addToken(LLKeywordToken::TOKEN_TYPE type, | ||
4589 | const std::string& key, | ||
4590 | const LLColor3& color, | ||
4591 | const std::string& tool_tip, | ||
4592 | const std::string& delimiter) | ||
4593 | { | ||
4594 | mKeywords.addToken(type,key,color,tool_tip); | ||
4595 | } | ||
4596 | |||
3955 | void LLTextEditor::updateSegments() | 4597 | void LLTextEditor::updateSegments() |
3956 | { | 4598 | { |
3957 | if (mKeywords.isLoaded()) | 4599 | if (mKeywords.isLoaded()) |
@@ -4385,6 +5027,10 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node) | |||
4385 | 5027 | ||
4386 | node->getAttributeBOOL("track_bottom", mTrackBottom); | 5028 | node->getAttributeBOOL("track_bottom", mTrackBottom); |
4387 | 5029 | ||
5030 | node->getAttributeBOOL("spell_check", mSpellCheckable); | ||
5031 | |||
5032 | node->getAttributeBOOL("allow_translate", mAllowTranslate); | ||
5033 | |||
4388 | LLColor4 color; | 5034 | LLColor4 color; |
4389 | if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) | 5035 | if (LLUICtrlFactory::getAttributeColor(node,"cursor_color", color)) |
4390 | { | 5036 | { |
@@ -4417,11 +5063,9 @@ S32 LLTextEditor::findHTMLToken(const std::string &line, S32 pos, BOOL reverse) | |||
4417 | std::string openers=" \t\n('\"[{<>"; | 5063 | std::string openers=" \t\n('\"[{<>"; |
4418 | std::string closers=" \t\n)'\"]}><;"; | 5064 | std::string closers=" \t\n)'\"]}><;"; |
4419 | 5065 | ||
4420 | S32 index = 0; | ||
4421 | |||
4422 | if (reverse) | 5066 | if (reverse) |
4423 | { | 5067 | { |
4424 | for (index=pos; index >= 0; index--) | 5068 | for (int index=pos; index >= 0; index--) |
4425 | { | 5069 | { |
4426 | char c = line[index]; | 5070 | char c = line[index]; |
4427 | S32 m2 = openers.find(c); | 5071 | S32 m2 = openers.find(c); |
@@ -4430,13 +5074,13 @@ S32 LLTextEditor::findHTMLToken(const std::string &line, S32 pos, BOOL reverse) | |||
4430 | return index+1; | 5074 | return index+1; |
4431 | } | 5075 | } |
4432 | } | 5076 | } |
4433 | index = 0; // Can't be before first charater | 5077 | return 0; // index is -1, don't want to return that. |
4434 | } | 5078 | } |
4435 | else | 5079 | else |
4436 | { | 5080 | { |
4437 | // adjust the search slightly, to allow matching parenthesis inside the URL | 5081 | // adjust the search slightly, to allow matching parenthesis inside the URL |
4438 | S32 paren_count = 0; | 5082 | S32 paren_count = 0; |
4439 | for (index=pos; index<(S32)line.length(); index++) | 5083 | for (int index=pos; index<(S32)line.length(); index++) |
4440 | { | 5084 | { |
4441 | char c = line[index]; | 5085 | char c = line[index]; |
4442 | 5086 | ||
@@ -4464,12 +5108,11 @@ S32 LLTextEditor::findHTMLToken(const std::string &line, S32 pos, BOOL reverse) | |||
4464 | } | 5108 | } |
4465 | } | 5109 | } |
4466 | } | 5110 | } |
5111 | return line.length(); | ||
4467 | } | 5112 | } |
4468 | |||
4469 | return index; | ||
4470 | } | 5113 | } |
4471 | 5114 | ||
4472 | BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end) const | 5115 | BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end, std::string& url) const |
4473 | { | 5116 | { |
4474 | 5117 | ||
4475 | S32 m1,m2,m3; | 5118 | S32 m1,m2,m3; |
@@ -4481,34 +5124,21 @@ BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end) const | |||
4481 | { | 5124 | { |
4482 | *begin = findHTMLToken(line, m1, TRUE); | 5125 | *begin = findHTMLToken(line, m1, TRUE); |
4483 | *end = findHTMLToken(line, m1, FALSE); | 5126 | *end = findHTMLToken(line, m1, FALSE); |
4484 | |||
4485 | // Can't start before the first char | ||
4486 | if(*begin < 0) | ||
4487 | { | ||
4488 | //*begin = 0; | ||
4489 | } | ||
4490 | 5127 | ||
4491 | //Load_url only handles http and https so don't hilite ftp, smb, etc. | 5128 | //Load_url only handles http and https so don't hilite ftp, smb, etc. |
4492 | try | 5129 | m2 = line.substr(*begin,(m1 - *begin)).find("http"); |
5130 | m3 = line.substr(*begin,(m1 - *begin)).find("secondlife"); | ||
5131 | |||
5132 | std::string badneighbors=".,<>?';\"][}{=-+_)(*&^%$#@!~`\t\r\n\\"; | ||
5133 | |||
5134 | if (m2 >= 0 || m3>=0) | ||
4493 | { | 5135 | { |
4494 | m2 = line.substr(*begin,(m1 - *begin)).find("http"); | 5136 | S32 bn = badneighbors.find(line.substr(m1+3,1)); |
4495 | m3 = line.substr(*begin,(m1 - *begin)).find("secondlife"); | 5137 | |
4496 | 5138 | if (bn < 0) | |
4497 | std::string badneighbors=".,<>?';\"][}{=-+_)(*&^%$#@!~`\t\r\n\\"; | 5139 | { |
4498 | 5140 | matched = TRUE; | |
4499 | if (m2 >= 0 || m3>=0) | ||
4500 | { | ||
4501 | S32 bn = badneighbors.find(line.substr(m1+3,1)); | ||
4502 | |||
4503 | if (bn < 0) | ||
4504 | { | ||
4505 | matched = TRUE; | ||
4506 | } | ||
4507 | } | 5141 | } |
4508 | } | ||
4509 | catch ( std::out_of_range outOfRange ) | ||
4510 | { | ||
4511 | LL_WARNS("TextEditor") << "got std::out_of_range exception \"" << line << "\"" << LL_ENDL; | ||
4512 | } | 5142 | } |
4513 | } | 5143 | } |
4514 | /* matches things like secondlife.com (no http://) needs a whitelist to really be effective. | 5144 | /* matches things like secondlife.com (no http://) needs a whitelist to really be effective. |
@@ -4541,34 +5171,35 @@ BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end) const | |||
4541 | { | 5171 | { |
4542 | S32 strpos, strpos2; | 5172 | S32 strpos, strpos2; |
4543 | 5173 | ||
5174 | // Is this try here still needed considering the changes to LLTextEditor::findHTMLToken? - MC | ||
4544 | try | 5175 | try |
4545 | { | 5176 | { |
4546 | std::string url = line.substr(*begin,*end - *begin); | 5177 | url = line.substr(*begin,*end - *begin); |
4547 | std::string slurlID = "slurl.com/secondlife/"; | 5178 | std::string slurlID = "slurl.com/secondlife/"; |
4548 | strpos = url.find(slurlID); | 5179 | strpos = url.find(slurlID); |
4549 | 5180 | ||
4550 | if (strpos < 0) | 5181 | if (strpos < 0) |
4551 | { | 5182 | { |
4552 | slurlID="maps.secondlife.com/secondlife/"; | 5183 | slurlID="maps.secondlife.com/secondlife/"; |
4553 | strpos = url.find(slurlID); | 5184 | strpos = url.find(slurlID); |
4554 | } | 5185 | } |
4555 | 5186 | ||
4556 | if (strpos < 0) | 5187 | if (strpos < 0) |
4557 | { | 5188 | { |
4558 | slurlID="secondlife://"; | 5189 | slurlID="secondlife://"; |
4559 | strpos = url.find(slurlID); | 5190 | strpos = url.find(slurlID); |
4560 | } | 5191 | } |
4561 | 5192 | ||
4562 | if (strpos < 0) | 5193 | if (strpos < 0) |
4563 | { | 5194 | { |
4564 | slurlID="sl://"; | 5195 | slurlID="sl://"; |
4565 | strpos = url.find(slurlID); | 5196 | strpos = url.find(slurlID); |
4566 | } | 5197 | } |
4567 | 5198 | ||
4568 | if (strpos >= 0) | 5199 | if (strpos >= 0) |
4569 | { | 5200 | { |
4570 | strpos+=slurlID.length(); | 5201 | strpos+=slurlID.length(); |
4571 | 5202 | ||
4572 | while ( ( strpos2=url.find("/",strpos) ) == -1 ) | 5203 | while ( ( strpos2=url.find("/",strpos) ) == -1 ) |
4573 | { | 5204 | { |
4574 | if ((*end+2) >= (S32)line.length() || line.substr(*end,1) != " " ) | 5205 | if ((*end+2) >= (S32)line.length() || line.substr(*end,1) != " " ) |
@@ -4576,19 +5207,18 @@ BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end) const | |||
4576 | matched=FALSE; | 5207 | matched=FALSE; |
4577 | break; | 5208 | break; |
4578 | } | 5209 | } |
4579 | 5210 | ||
4580 | strpos = (*end + 1) - *begin; | 5211 | strpos = (*end + 1) - *begin; |
4581 | 5212 | ||
4582 | *end = findHTMLToken(line,(*begin + strpos),FALSE); | 5213 | *end = findHTMLToken(line,(*begin + strpos),FALSE); |
4583 | url = line.substr(*begin,*end - *begin); | 5214 | url = line.substr(*begin,*end - *begin); |
4584 | } | 5215 | } |
4585 | } | 5216 | } |
4586 | |||
4587 | } | 5217 | } |
4588 | 5218 | ||
4589 | catch ( std::out_of_range outOfRange ) | 5219 | catch ( std::out_of_range outOfRange ) |
4590 | { | 5220 | { |
4591 | LL_WARNS("TextEditor") << "got std::out_of_range exception \"" << line << "\"" << LL_ENDL; | 5221 | llwarns << "got std::out_of_range exception \"" << line << "\"" << llendl; |
4592 | } | 5222 | } |
4593 | } | 5223 | } |
4594 | 5224 | ||
diff --git a/linden/indra/llui/lltexteditor.h b/linden/indra/llui/lltexteditor.h index f26bf3b..759cd69 100644 --- a/linden/indra/llui/lltexteditor.h +++ b/linden/indra/llui/lltexteditor.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "lldarray.h" | 45 | #include "lldarray.h" |
46 | 46 | ||
47 | #include "llpreeditor.h" | 47 | #include "llpreeditor.h" |
48 | #include "llmenugl.h" | ||
48 | 49 | ||
49 | class LLFontGL; | 50 | class LLFontGL; |
50 | class LLScrollbar; | 51 | class LLScrollbar; |
@@ -84,6 +85,7 @@ public: | |||
84 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); | 85 | virtual BOOL handleHover(S32 x, S32 y, MASK mask); |
85 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); | 86 | virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); |
86 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); | 87 | virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask ); |
88 | virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask ); | ||
87 | virtual BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); | 89 | virtual BOOL handleMiddleMouseDown(S32 x,S32 y,MASK mask); |
88 | 90 | ||
89 | virtual BOOL handleKeyHere(KEY key, MASK mask ); | 91 | virtual BOOL handleKeyHere(KEY key, MASK mask ); |
@@ -108,23 +110,40 @@ public: | |||
108 | virtual void setFocus( BOOL b ); | 110 | virtual void setFocus( BOOL b ); |
109 | virtual BOOL acceptsTextInput() const; | 111 | virtual BOOL acceptsTextInput() const; |
110 | virtual BOOL isDirty() const { return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); } | 112 | virtual BOOL isDirty() const { return( mLastCmd != NULL || (mPristineCmd && (mPristineCmd != mLastCmd)) ); } |
113 | BOOL isSpellDirty() const { return mWText != mPrevSpelledText; } // Returns TRUE if user changed value at all | ||
114 | void resetSpellDirty() { mPrevSpelledText = mWText; } // Clear dirty state | ||
111 | 115 | ||
116 | struct SpellMenuBind | ||
117 | { | ||
118 | LLTextEditor* origin; | ||
119 | LLMenuItemCallGL * menuItem; | ||
120 | std::string word; | ||
121 | S32 wordPositionStart; | ||
122 | S32 wordPositionEnd; | ||
123 | S32 wordY; | ||
124 | }; | ||
125 | |||
112 | // LLEditMenuHandler interface | 126 | // LLEditMenuHandler interface |
113 | virtual void undo(); | 127 | virtual void undo(); |
114 | virtual BOOL canUndo() const; | 128 | virtual BOOL canUndo() const; |
115 | virtual void redo(); | 129 | virtual void redo(); |
116 | virtual BOOL canRedo() const; | 130 | virtual BOOL canRedo() const; |
117 | |||
118 | virtual void cut(); | 131 | virtual void cut(); |
119 | virtual BOOL canCut() const; | 132 | virtual BOOL canCut() const; |
120 | virtual void copy(); | 133 | virtual void copy(); |
121 | virtual BOOL canCopy() const; | 134 | virtual BOOL canCopy() const; |
122 | virtual void paste(); | 135 | virtual void paste(); |
123 | virtual BOOL canPaste() const; | 136 | virtual BOOL canPaste() const; |
137 | |||
138 | virtual void spellReplace(SpellMenuBind* spellData); | ||
139 | virtual void translationReplace(const std::string &translation, const S32 orig_start, const S32 orig_length); | ||
140 | virtual BOOL canTranslate() const; | ||
141 | |||
124 | virtual void updatePrimary(); | 142 | virtual void updatePrimary(); |
125 | virtual void copyPrimary(); | 143 | virtual void copyPrimary(); |
126 | virtual void pastePrimary(); | 144 | virtual void pastePrimary(); |
127 | virtual BOOL canPastePrimary() const; | 145 | virtual BOOL canPastePrimary() const; |
146 | |||
128 | virtual void doDelete(); | 147 | virtual void doDelete(); |
129 | virtual BOOL canDoDelete() const; | 148 | virtual BOOL canDoDelete() const; |
130 | virtual void selectAll(); | 149 | virtual void selectAll(); |
@@ -132,6 +151,26 @@ public: | |||
132 | virtual void deselect(); | 151 | virtual void deselect(); |
133 | virtual BOOL canDeselect() const; | 152 | virtual BOOL canDeselect() const; |
134 | 153 | ||
154 | static BOOL context_enable_cut(void* data); | ||
155 | static void context_cut(void* data); | ||
156 | static BOOL context_enable_copy(void* data); | ||
157 | static void context_copy(void* data); | ||
158 | static BOOL context_enable_paste(void* data); | ||
159 | static void context_paste(void* data); | ||
160 | static BOOL context_enable_delete(void* data); | ||
161 | static void context_delete(void* data); | ||
162 | static BOOL context_enable_selectall(void* data); | ||
163 | static void context_selectall(void* data); | ||
164 | static BOOL context_enable_translate(void * data); | ||
165 | static void context_translate(void * data); | ||
166 | static void spell_correct(void* data); | ||
167 | static void spell_add(void* data); | ||
168 | static void spell_show(void* data); | ||
169 | |||
170 | void getMisspelledWordsPositions(std::vector<S32>& misspell_positions); | ||
171 | |||
172 | void defineMenuCallbacks(LLMenuGL* menu); | ||
173 | |||
135 | void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); | 174 | void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); |
136 | BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); | 175 | BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); |
137 | void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); | 176 | void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); |
@@ -145,17 +184,17 @@ public: | |||
145 | BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; } | 184 | BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; } |
146 | 185 | ||
147 | // inserts text at cursor | 186 | // inserts text at cursor |
148 | void insertText(const std::string &text); | 187 | void insertText(const std::string &text, BOOL deleteSelection = TRUE); |
149 | // appends text at end | 188 | // appends text at end |
150 | void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline, | 189 | void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline, |
151 | const LLStyleSP stylep = NULL); | 190 | const LLStyleSP stylep = NULL); |
152 | 191 | ||
153 | void appendColoredText(const std::string &wtext, bool allow_undo, | 192 | void appendColoredText(const std::string &wtext, bool allow_undo, |
154 | bool prepend_newline, | 193 | bool prepend_newline, |
155 | const LLColor4 &color, | 194 | const LLColor4 &color, |
156 | const std::string& font_name = LLStringUtil::null); | 195 | const std::string& font_name = LLStringUtil::null); |
157 | // if styled text starts a line, you need to prepend a newline. | 196 | // if styled text starts a line, you need to prepend a newline. |
158 | void appendStyledText(const std::string &new_text, bool allow_undo, | 197 | void appendStyledText(const std::string &new_text, bool allow_undo, |
159 | bool prepend_newline, | 198 | bool prepend_newline, |
160 | LLStyleSP stylep = NULL); | 199 | LLStyleSP stylep = NULL); |
161 | void appendHighlightedText(const std::string &new_text, bool allow_undo, | 200 | void appendHighlightedText(const std::string &new_text, bool allow_undo, |
@@ -182,6 +221,11 @@ public: | |||
182 | const std::vector<std::string>& funcs, | 221 | const std::vector<std::string>& funcs, |
183 | const std::vector<std::string>& tooltips, | 222 | const std::vector<std::string>& tooltips, |
184 | const LLColor3& func_color); | 223 | const LLColor3& func_color); |
224 | void addToken(LLKeywordToken::TOKEN_TYPE type, | ||
225 | const std::string& key, | ||
226 | const LLColor3& color, | ||
227 | const std::string& tool_tip = LLStringUtil::null, | ||
228 | const std::string& delimiter = LLStringUtil::null); | ||
185 | LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); } | 229 | LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); } |
186 | LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); } | 230 | LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); } |
187 | 231 | ||
@@ -196,6 +240,7 @@ public: | |||
196 | void setThumbColor( const LLColor4& color ); | 240 | void setThumbColor( const LLColor4& color ); |
197 | void setHighlightColor( const LLColor4& color ); | 241 | void setHighlightColor( const LLColor4& color ); |
198 | void setShadowColor( const LLColor4& color ); | 242 | void setShadowColor( const LLColor4& color ); |
243 | void setSpellCheckable(BOOL b) { mSpellCheckable = b; } | ||
199 | 244 | ||
200 | // Hacky methods to make it into a word-wrapping, potentially scrolling, | 245 | // Hacky methods to make it into a word-wrapping, potentially scrolling, |
201 | // read-only text box. | 246 | // read-only text box. |
@@ -262,7 +307,7 @@ public: | |||
262 | const LLTextSegment* getPreviousSegment() const; | 307 | const LLTextSegment* getPreviousSegment() const; |
263 | void getSelectedSegments(std::vector<const LLTextSegment*>& segments) const; | 308 | void getSelectedSegments(std::vector<const LLTextSegment*>& segments) const; |
264 | 309 | ||
265 | static bool isPartOfWord(llwchar c) { return (c == '_') || LLStringOps::isAlnum((char)c); } | 310 | static bool isPartOfWord(llwchar c) { return ( (c == '_') || (c == '\'') || LLStringOps::isAlnum((char)c)); } |
266 | 311 | ||
267 | BOOL isReadOnly() { return mReadOnly; } | 312 | BOOL isReadOnly() { return mReadOnly; } |
268 | protected: | 313 | protected: |
@@ -270,11 +315,14 @@ protected: | |||
270 | // Methods | 315 | // Methods |
271 | // | 316 | // |
272 | 317 | ||
318 | LLHandle<LLView> mPopupMenuHandle; | ||
319 | |||
273 | S32 getLength() const { return mWText.length(); } | 320 | S32 getLength() const { return mWText.length(); } |
274 | void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const; | 321 | void getSegmentAndOffset( S32 startpos, S32* segidxp, S32* offsetp ) const; |
275 | void drawPreeditMarker(); | 322 | void drawPreeditMarker(); |
276 | 323 | public: | |
277 | void updateLineStartList(S32 startpos = 0); | 324 | void updateLineStartList(S32 startpos = 0); |
325 | protected: | ||
278 | void updateScrollFromCursor(); | 326 | void updateScrollFromCursor(); |
279 | void updateTextRect(); | 327 | void updateTextRect(); |
280 | const LLRect& getTextRect() const { return mTextRect; } | 328 | const LLRect& getTextRect() const { return mTextRect; } |
@@ -301,8 +349,13 @@ protected: | |||
301 | BOOL handleSelectionKey(const KEY key, const MASK mask); | 349 | BOOL handleSelectionKey(const KEY key, const MASK mask); |
302 | BOOL handleControlKey(const KEY key, const MASK mask); | 350 | BOOL handleControlKey(const KEY key, const MASK mask); |
303 | BOOL handleEditKey(const KEY key, const MASK mask); | 351 | BOOL handleEditKey(const KEY key, const MASK mask); |
304 | 352 | // <edit> | |
353 | public: | ||
354 | // </edit> | ||
305 | BOOL hasSelection() const { return (mSelectionStart !=mSelectionEnd); } | 355 | BOOL hasSelection() const { return (mSelectionStart !=mSelectionEnd); } |
356 | // <edit> | ||
357 | protected: | ||
358 | // </edit> | ||
306 | BOOL selectionContainsLineBreaks(); | 359 | BOOL selectionContainsLineBreaks(); |
307 | void startSelection(); | 360 | void startSelection(); |
308 | void endSelection(); | 361 | void endSelection(); |
@@ -310,6 +363,7 @@ protected: | |||
310 | 363 | ||
311 | S32 prevWordPos(S32 cursorPos) const; | 364 | S32 prevWordPos(S32 cursorPos) const; |
312 | S32 nextWordPos(S32 cursorPos) const; | 365 | S32 nextWordPos(S32 cursorPos) const; |
366 | BOOL getWordBoundriesAt(const S32 at, S32* word_begin, S32* word_length) const; | ||
313 | 367 | ||
314 | S32 getLineCount() const { return mLineStartList.size(); } | 368 | S32 getLineCount() const { return mLineStartList.size(); } |
315 | S32 getLineStart( S32 line ) const; | 369 | S32 getLineStart( S32 line ) const; |
@@ -330,7 +384,7 @@ protected: | |||
330 | virtual void unbindEmbeddedChars(const LLFontGL* font) const {} | 384 | virtual void unbindEmbeddedChars(const LLFontGL* font) const {} |
331 | 385 | ||
332 | S32 findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const; | 386 | S32 findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const; |
333 | BOOL findHTML(const std::string &line, S32 *begin, S32 *end) const; | 387 | BOOL findHTML(const std::string &line, S32 *begin, S32 *end, std::string& url) const; |
334 | 388 | ||
335 | // Abstract inner base class representing an undoable editor command. | 389 | // Abstract inner base class representing an undoable editor command. |
336 | // Concrete sub-classes can be defined for operations such as insert, remove, etc. | 390 | // Concrete sub-classes can be defined for operations such as insert, remove, etc. |
@@ -400,8 +454,9 @@ protected: | |||
400 | // | 454 | // |
401 | 455 | ||
402 | // I-beam is just after the mCursorPos-th character. | 456 | // I-beam is just after the mCursorPos-th character. |
457 | public: | ||
403 | S32 mCursorPos; | 458 | S32 mCursorPos; |
404 | 459 | protected: | |
405 | // Use these to determine if a click on an embedded item is a drag or not. | 460 | // Use these to determine if a click on an embedded item is a drag or not. |
406 | S32 mMouseDownX; | 461 | S32 mMouseDownX; |
407 | S32 mMouseDownY; | 462 | S32 mMouseDownY; |
@@ -447,6 +502,8 @@ private: | |||
447 | void drawBackground(); | 502 | void drawBackground(); |
448 | void drawSelectionBackground(); | 503 | void drawSelectionBackground(); |
449 | void drawCursor(); | 504 | void drawCursor(); |
505 | void autoCorrectText(); | ||
506 | void drawMisspelled(); | ||
450 | void drawText(); | 507 | void drawText(); |
451 | void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& color, F32* right_x); | 508 | void drawClippedSegment(const LLWString &wtext, S32 seg_start, S32 seg_end, F32 x, F32 y, S32 selection_left, S32 selection_right, const LLStyleSP& color, F32* right_x); |
452 | 509 | ||
@@ -477,6 +534,13 @@ private: | |||
477 | mutable std::string mUTF8Text; | 534 | mutable std::string mUTF8Text; |
478 | mutable BOOL mTextIsUpToDate; | 535 | mutable BOOL mTextIsUpToDate; |
479 | 536 | ||
537 | LLWString mPrevSpelledText; // saved string so we know whether to respell or not | ||
538 | S32 spellStart; | ||
539 | S32 spellEnd; | ||
540 | std::vector<S32> mMisspellLocations; // where all the mispelled words are | ||
541 | BOOL mSpellCheckable; // set in xui as "spell_check". Default value for a field | ||
542 | BOOL mAllowTranslate; // set in xui as "allow_translate". | ||
543 | |||
480 | S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes | 544 | S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes |
481 | 545 | ||
482 | const LLFontGL* mGLFont; | 546 | const LLFontGL* mGLFont; |
@@ -513,11 +577,18 @@ private: | |||
513 | } | 577 | } |
514 | }; | 578 | }; |
515 | typedef std::vector<line_info> line_list_t; | 579 | typedef std::vector<line_info> line_list_t; |
580 | |||
581 | //to keep track of what we have to remove before showing menu | ||
582 | std::vector<SpellMenuBind* > suggestionMenuItems; | ||
583 | S32 mLastContextMenuX; | ||
584 | S32 mLastContextMenuY; | ||
585 | |||
516 | line_list_t mLineStartList; | 586 | line_list_t mLineStartList; |
517 | BOOL mReflowNeeded; | 587 | BOOL mReflowNeeded; |
518 | BOOL mScrollNeeded; | 588 | BOOL mScrollNeeded; |
519 | 589 | ||
520 | LLFrameTimer mKeystrokeTimer; | 590 | LLFrameTimer mKeystrokeTimer; |
591 | LLFrameTimer mSpellTimer; | ||
521 | 592 | ||
522 | LLColor4 mCursorColor; | 593 | LLColor4 mCursorColor; |
523 | 594 | ||
diff --git a/linden/indra/llui/lltextparser.cpp b/linden/indra/llui/lltextparser.cpp index 925b118..707dd0a 100644 --- a/linden/indra/llui/lltextparser.cpp +++ b/linden/indra/llui/lltextparser.cpp | |||
@@ -1,6 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * @file lltexteditor.cpp | 2 | * @file lltextparser.cpp |
3 | * @brief LLTextEditor base class | ||
4 | * | 3 | * |
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | 4 | * $LicenseInfo:firstyear=2001&license=viewergpl$ |
6 | * | 5 | * |
@@ -32,6 +31,8 @@ | |||
32 | 31 | ||
33 | #include "linden_common.h" | 32 | #include "linden_common.h" |
34 | 33 | ||
34 | #include "lltextparser.h" | ||
35 | |||
35 | #include "llsd.h" | 36 | #include "llsd.h" |
36 | #include "llsdserialize.h" | 37 | #include "llsdserialize.h" |
37 | #include "llerror.h" | 38 | #include "llerror.h" |
@@ -40,23 +41,13 @@ | |||
40 | #include "message.h" | 41 | #include "message.h" |
41 | #include "llmath.h" | 42 | #include "llmath.h" |
42 | #include "v4color.h" | 43 | #include "v4color.h" |
43 | #include "audioengine.h" | ||
44 | #include "llwindow.h" | ||
45 | #include "lldir.h" | 44 | #include "lldir.h" |
46 | 45 | ||
47 | #include "lltextparser.h" | ||
48 | //#include "lltexttospeech.h" | ||
49 | |||
50 | // Routines used for parsing text for TextParsers and html | 46 | // Routines used for parsing text for TextParsers and html |
51 | 47 | ||
52 | LLTextParser* LLTextParser::sInstance = NULL; | 48 | LLTextParser* LLTextParser::sInstance = NULL; |
53 | 49 | ||
54 | // | 50 | // |
55 | // Constants | ||
56 | // | ||
57 | const F32 SOUND_GAIN = 1.0f; | ||
58 | |||
59 | // | ||
60 | // Member Functions | 51 | // Member Functions |
61 | // | 52 | // |
62 | 53 | ||
@@ -76,38 +67,7 @@ LLTextParser* LLTextParser::getInstance() | |||
76 | return sInstance; | 67 | return sInstance; |
77 | } | 68 | } |
78 | 69 | ||
79 | void LLTextParser::triggerAlerts(LLUUID agent_id, LLVector3d position, std::string text, LLWindow* viewer_window) | 70 | // Moved triggerAlerts() to llfloaterchat.cpp to break llui/llaudio library dependency. |
80 | { | ||
81 | // bool spoken=FALSE; | ||
82 | for (S32 i=0;i<mHighlights.size();i++) | ||
83 | { | ||
84 | if (findPattern(text,mHighlights[i]) >= 0 ) | ||
85 | { | ||
86 | if(gAudiop) | ||
87 | { | ||
88 | if ((std::string)mHighlights[i]["sound_lluuid"] != LLUUID::null.asString()) | ||
89 | { | ||
90 | gAudiop->triggerSound(mHighlights[i]["sound_lluuid"].asUUID(), agent_id, SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, position); | ||
91 | } | ||
92 | /* | ||
93 | if (!spoken) | ||
94 | { | ||
95 | LLTextToSpeech* text_to_speech = NULL; | ||
96 | text_to_speech = LLTextToSpeech::getInstance(); | ||
97 | spoken = text_to_speech->speak((LLString)mHighlights[i]["voice"],text); | ||
98 | } | ||
99 | */ | ||
100 | } | ||
101 | if (mHighlights[i]["flash"]) | ||
102 | { | ||
103 | if (viewer_window && viewer_window->getMinimized()) | ||
104 | { | ||
105 | viewer_window->flashIcon(5.f); | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | 71 | ||
112 | S32 LLTextParser::findPattern(const std::string &text, LLSD highlight) | 72 | S32 LLTextParser::findPattern(const std::string &text, LLSD highlight) |
113 | { | 73 | { |
diff --git a/linden/indra/llui/lltextparser.h b/linden/indra/llui/lltextparser.h index d69e3a2..32343a2 100644 --- a/linden/indra/llui/lltextparser.h +++ b/linden/indra/llui/lltextparser.h | |||
@@ -34,12 +34,8 @@ | |||
34 | #ifndef LL_LLTEXTPARSER_H | 34 | #ifndef LL_LLTEXTPARSER_H |
35 | #define LL_LLTEXTPARSER_H | 35 | #define LL_LLTEXTPARSER_H |
36 | 36 | ||
37 | #include <vector> | 37 | #include "llsd.h" |
38 | #include "linden_common.h" | ||
39 | 38 | ||
40 | #include "lltextparser.h" | ||
41 | |||
42 | class LLSD; | ||
43 | class LLUUID; | 39 | class LLUUID; |
44 | class LLVector3d; | 40 | class LLVector3d; |
45 | class LLColor4; | 41 | class LLColor4; |
@@ -59,7 +55,6 @@ public: | |||
59 | S32 findPattern(const std::string &text, LLSD highlight); | 55 | S32 findPattern(const std::string &text, LLSD highlight); |
60 | LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color,S32 part=WHOLE, S32 index=0); | 56 | LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color,S32 part=WHOLE, S32 index=0); |
61 | bool parseFullLineHighlights(const std::string &text, LLColor4 *color); | 57 | bool parseFullLineHighlights(const std::string &text, LLColor4 *color); |
62 | void triggerAlerts(LLUUID agent_id, LLVector3d position, std::string text, LLWindow* viewer_window); | ||
63 | 58 | ||
64 | std::string getFileName(); | 59 | std::string getFileName(); |
65 | LLSD loadFromDisk(); | 60 | LLSD loadFromDisk(); |
diff --git a/linden/indra/llui/llui.cpp b/linden/indra/llui/llui.cpp index 57ce13c..75a4467 100644 --- a/linden/indra/llui/llui.cpp +++ b/linden/indra/llui/llui.cpp | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <map> | 38 | #include <map> |
39 | 39 | ||
40 | // Linden library includes | 40 | // Linden library includes |
41 | #include "audioengine.h" | ||
42 | #include "v2math.h" | 41 | #include "v2math.h" |
43 | #include "v4color.h" | 42 | #include "v4color.h" |
44 | #include "llrender.h" | 43 | #include "llrender.h" |
diff --git a/linden/indra/llui/lluictrl.cpp b/linden/indra/llui/lluictrl.cpp index 9d97312..3f4ab5e 100644 --- a/linden/indra/llui/lluictrl.cpp +++ b/linden/indra/llui/lluictrl.cpp | |||
@@ -39,54 +39,7 @@ | |||
39 | 39 | ||
40 | static LLRegisterWidget<LLUICtrl> r("ui_ctrl"); | 40 | static LLRegisterWidget<LLUICtrl> r("ui_ctrl"); |
41 | 41 | ||
42 | LLFocusableElement::LLFocusableElement() | 42 | // NOTE: the LLFocusableElement implementation has been moved to llfocusmgr.cpp, to mirror the header where the class is defined. |
43 | : mFocusLostCallback(NULL), | ||
44 | mFocusReceivedCallback(NULL), | ||
45 | mFocusChangedCallback(NULL), | ||
46 | mFocusCallbackUserData(NULL) | ||
47 | { | ||
48 | } | ||
49 | |||
50 | //virtual | ||
51 | LLFocusableElement::~LLFocusableElement() | ||
52 | { | ||
53 | } | ||
54 | |||
55 | void LLFocusableElement::onFocusReceived() | ||
56 | { | ||
57 | if( mFocusReceivedCallback ) | ||
58 | { | ||
59 | mFocusReceivedCallback( this, mFocusCallbackUserData ); | ||
60 | } | ||
61 | if( mFocusChangedCallback ) | ||
62 | { | ||
63 | mFocusChangedCallback( this, mFocusCallbackUserData ); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | void LLFocusableElement::onFocusLost() | ||
68 | { | ||
69 | if( mFocusLostCallback ) | ||
70 | { | ||
71 | mFocusLostCallback( this, mFocusCallbackUserData ); | ||
72 | } | ||
73 | |||
74 | if( mFocusChangedCallback ) | ||
75 | { | ||
76 | mFocusChangedCallback( this, mFocusCallbackUserData ); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | BOOL LLFocusableElement::hasFocus() const | ||
81 | { | ||
82 | return FALSE; | ||
83 | } | ||
84 | |||
85 | void LLFocusableElement::setFocus(BOOL b) | ||
86 | { | ||
87 | } | ||
88 | |||
89 | |||
90 | 43 | ||
91 | LLUICtrl::LLUICtrl() : | 44 | LLUICtrl::LLUICtrl() : |
92 | mCommitCallback(NULL), | 45 | mCommitCallback(NULL), |
@@ -212,7 +165,7 @@ void LLUICtrl::onFocusReceived() | |||
212 | 165 | ||
213 | // find first view in hierarchy above new focus that is a LLUICtrl | 166 | // find first view in hierarchy above new focus that is a LLUICtrl |
214 | LLView* viewp = getParent(); | 167 | LLView* viewp = getParent(); |
215 | LLUICtrl* last_focus = gFocusMgr.getLastKeyboardFocus(); | 168 | LLUICtrl* last_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getLastKeyboardFocus()); |
216 | 169 | ||
217 | while (viewp && !viewp->isCtrl()) | 170 | while (viewp && !viewp->isCtrl()) |
218 | { | 171 | { |
@@ -590,6 +543,10 @@ void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) ) | |||
590 | // virtual | 543 | // virtual |
591 | void LLUICtrl::setColor(const LLColor4& color) | 544 | void LLUICtrl::setColor(const LLColor4& color) |
592 | { } | 545 | { } |
546 | // virtual | ||
547 | |||
548 | void LLUICtrl::setAlpha(F32 alpha) | ||
549 | { } | ||
593 | 550 | ||
594 | // virtual | 551 | // virtual |
595 | void LLUICtrl::setMinValue(LLSD min_value) | 552 | void LLUICtrl::setMinValue(LLSD min_value) |
diff --git a/linden/indra/llui/lluictrl.h b/linden/indra/llui/lluictrl.h index db41af8..be8e863 100644 --- a/linden/indra/llui/lluictrl.h +++ b/linden/indra/llui/lluictrl.h | |||
@@ -39,31 +39,8 @@ | |||
39 | #include "llsd.h" | 39 | #include "llsd.h" |
40 | 40 | ||
41 | 41 | ||
42 | class LLFocusableElement | ||
43 | { | ||
44 | friend class LLFocusMgr; // allow access to focus change handlers | ||
45 | public: | ||
46 | LLFocusableElement(); | ||
47 | virtual ~LLFocusableElement(); | ||
48 | |||
49 | virtual void setFocus( BOOL b ); | ||
50 | virtual BOOL hasFocus() const; | ||
51 | |||
52 | void setFocusLostCallback(void (*cb)(LLFocusableElement* caller, void*), void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; } | ||
53 | void setFocusReceivedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; } | ||
54 | void setFocusChangedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; } | ||
55 | |||
56 | protected: | ||
57 | virtual void onFocusReceived(); | ||
58 | virtual void onFocusLost(); | ||
59 | void (*mFocusLostCallback)( LLFocusableElement* caller, void* userdata ); | ||
60 | void (*mFocusReceivedCallback)( LLFocusableElement* ctrl, void* userdata ); | ||
61 | void (*mFocusChangedCallback)( LLFocusableElement* ctrl, void* userdata ); | ||
62 | void* mFocusCallbackUserData; | ||
63 | }; | ||
64 | |||
65 | class LLUICtrl | 42 | class LLUICtrl |
66 | : public LLView, public LLFocusableElement | 43 | : public LLView |
67 | { | 44 | { |
68 | public: | 45 | public: |
69 | typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); | 46 | typedef void (*LLUICtrlCallback)(LLUICtrl* ctrl, void* userdata); |
@@ -117,6 +94,7 @@ public: | |||
117 | virtual void clear(); | 94 | virtual void clear(); |
118 | virtual void setDoubleClickCallback( void (*cb)(void*) ); | 95 | virtual void setDoubleClickCallback( void (*cb)(void*) ); |
119 | virtual void setColor(const LLColor4& color); | 96 | virtual void setColor(const LLColor4& color); |
97 | virtual void setAlpha(F32 alpha); | ||
120 | virtual void setMinValue(LLSD min_value); | 98 | virtual void setMinValue(LLSD min_value); |
121 | virtual void setMaxValue(LLSD max_value); | 99 | virtual void setMaxValue(LLSD max_value); |
122 | 100 | ||
diff --git a/linden/indra/llui/lluixmltags.h b/linden/indra/llui/lluixmltags.h index 4166131..6bbb788 100644 --- a/linden/indra/llui/lluixmltags.h +++ b/linden/indra/llui/lluixmltags.h | |||
@@ -32,100 +32,100 @@ | |||
32 | #ifndef LL_UI_XML_TAGS_H | 32 | #ifndef LL_UI_XML_TAGS_H |
33 | #define LL_UI_XML_TAGS_H | 33 | #define LL_UI_XML_TAGS_H |
34 | 34 | ||
35 | const std::string | 35 | char const* const LL_BUTTON_TAG = "button"; |
36 | LL_BUTTON_TAG("button"), | 36 | char const* const LL_UI_CTRL_LOCATE_TAG = "locate"; |
37 | LL_UI_CTRL_LOCATE_TAG("locate"), | 37 | char const* const LL_PAD_TAG = "pad"; |
38 | LL_PAD_TAG("pad"), | 38 | char const* const LL_CHECK_BOX_CTRL_TAG = "check_box"; |
39 | LL_CHECK_BOX_CTRL_TAG("check_box"), | 39 | char const* const LL_COMBO_BOX_TAG = "combo_box"; |
40 | LL_COMBO_BOX_TAG("combo_box"), | 40 | char const* const LL_DRAG_HANDLE_TOP_TAG = "drag_handle_top"; |
41 | LL_DRAG_HANDLE_TOP_TAG("drag_handle_top"), | 41 | char const* const LL_DRAG_HANDLE_LEFT_TAG = "drag_handle_left"; |
42 | LL_DRAG_HANDLE_LEFT_TAG("drag_handle_left"), | 42 | char const* const LL_FLOATER_TAG = "floater"; |
43 | LL_FLOATER_TAG("floater"), | 43 | char const* const LL_FLOATER_VIEW_TAG = "floater_view"; |
44 | LL_FLOATER_VIEW_TAG("floater_view"), | 44 | char const* const LL_MULTI_FLOATER_TAG = "multi_floater"; |
45 | LL_MULTI_FLOATER_TAG("multi_floater"), | 45 | char const* const LL_ICON_CTRL_TAG = "icon"; |
46 | LL_ICON_CTRL_TAG("icon"), | 46 | char const* const LL_LINE_EDITOR_TAG = "line_editor"; |
47 | LL_LINE_EDITOR_TAG("line_editor"), | 47 | char const* const LL_SEARCH_EDITOR_TAG = "search_editor"; |
48 | LL_SEARCH_EDITOR_TAG("search_editor"), | 48 | char const* const LL_MENU_ITEM_TAG = "menu_item"; |
49 | LL_MENU_ITEM_TAG("menu_item"), | 49 | char const* const LL_MENU_GL_TAG = "menu"; |
50 | LL_MENU_GL_TAG("menu"), | 50 | char const* const LL_MENU_BAR_GL_TAG = "menu_bar"; |
51 | LL_MENU_BAR_GL_TAG("menu_bar"), | 51 | char const* const LL_MENU_HOLDER_GL_TAG = "menu_holder"; |
52 | LL_MENU_HOLDER_GL_TAG("menu_holder"), | 52 | char const* const LL_PANEL_TAG = "panel"; |
53 | LL_PANEL_TAG("panel"), | 53 | char const* const LL_RADIO_GROUP_TAG = "radio_group"; |
54 | LL_RADIO_GROUP_TAG("radio_group"), | 54 | char const* const LL_RESIZE_BAR_TAG = "resize_bar"; |
55 | LL_RESIZE_BAR_TAG("resize_bar"), | 55 | char const* const LL_RESIZE_HANDLE_TAG = "resize_handle"; |
56 | LL_RESIZE_HANDLE_TAG("resize_handle"), | 56 | char const* const LL_SCROLLBAR_TAG = "scrollbar"; |
57 | LL_SCROLLBAR_TAG("scrollbar"), | 57 | char const* const LL_SCROLLABLE_CONTAINER_VIEW_TAG = "scroll_container"; |
58 | LL_SCROLLABLE_CONTAINER_VIEW_TAG("scroll_container"), | 58 | char const* const LL_SCROLL_LIST_CTRL_TAG = "scroll_list"; |
59 | LL_SCROLL_LIST_CTRL_TAG("scroll_list"), | 59 | char const* const LL_SLIDER_CTRL_TAG = "slider"; |
60 | LL_SLIDER_CTRL_TAG("slider"), | 60 | char const* const LL_SLIDER_TAG = "slider_bar"; |
61 | LL_SLIDER_TAG("slider_bar"), | 61 | char const* const LL_MULTI_SLIDER_CTRL_TAG = "multi_slider"; |
62 | LL_MULTI_SLIDER_CTRL_TAG("multi_slider"), | 62 | char const* const LL_MULTI_SLIDER_TAG = "multi_slider_bar"; |
63 | LL_MULTI_SLIDER_TAG("multi_slider_bar"), | 63 | char const* const LL_SPIN_CTRL_TAG = "spinner"; |
64 | LL_SPIN_CTRL_TAG("spinner"), | 64 | char const* const LL_TAB_CONTAINER_COMMON_TAG = "tab_container"; |
65 | LL_TAB_CONTAINER_COMMON_TAG("tab_container"), | 65 | char const* const LL_TEXT_BOX_TAG = "text"; |
66 | LL_TEXT_BOX_TAG("text"), | 66 | char const* const LL_TEXT_EDITOR_TAG = "text_editor"; |
67 | LL_TEXT_EDITOR_TAG("text_editor"), | 67 | char const* const LL_VIEW_BORDER_TAG = "view_border"; |
68 | LL_VIEW_BORDER_TAG("view_border"), | 68 | char const* const LL_COLOR_SWATCH_TAG = "color_swatch"; |
69 | LL_COLOR_SWATCH_TAG("color_swatch"), | 69 | char const* const LL_INVENTORY_PANEL_TAG = "inventory_panel"; |
70 | LL_INVENTORY_PANEL_TAG("inventory_panel"), | 70 | char const* const LL_NAME_EDITOR_TAG = "name_editor"; |
71 | LL_NAME_EDITOR_TAG("name_editor"), | 71 | char const* const LL_NAME_LIST_TAG = "name_list"; |
72 | LL_NAME_LIST_TAG("name_list"), | 72 | char const* const LL_TEXTURE_PICKER_TAG = "texture_picker"; |
73 | LL_TEXTURE_PICKER_TAG("texture_picker"), | 73 | char const* const LL_VOLUME_SLIDER_CTRL_TAG = "volume_slider"; |
74 | LL_VOLUME_SLIDER_CTRL_TAG("volume_slider"), | 74 | char const* const LL_WEB_BROWSER_CTRL_TAG = "web_browser"; |
75 | LL_WEB_BROWSER_CTRL_TAG("web_browser"), | 75 | char const* const LL_STAT_VIEW_TAG = "stat_view"; |
76 | LL_STAT_VIEW_TAG("stat_view"), | 76 | char const* const LL_PROGRESS_VIEW_TAG = "progress_view"; |
77 | LL_PROGRESS_VIEW_TAG("progress_view"), | 77 | char const* const LL_STAT_BAR_TAG = "stat_bar"; |
78 | LL_STAT_BAR_TAG("stat_bar"), | 78 | char const* const LL_STATUS_BAR_TAG = "status_bar"; |
79 | LL_STATUS_BAR_TAG("status_bar"), | 79 | char const* const LL_VIEWER_TEXT_EDITOR_TAG = "viewer_text_editor"; |
80 | LL_VIEWER_TEXT_EDITOR_TAG("viewer_text_editor"), | 80 | char const* const LL_TALK_VIEW_TAG = "talk_view"; |
81 | LL_TALK_VIEW_TAG("talk_view"), | 81 | char const* const LL_COLOR_SWATCH_CTRL_TAG = "color_swatch"; |
82 | LL_COLOR_SWATCH_CTRL_TAG("color_swatch"), | 82 | char const* const LL_GL_TEX_MEM_BAR_TAG = "tex_mem_bar"; |
83 | LL_GL_TEX_MEM_BAR_TAG("tex_mem_bar"), | 83 | char const* const LL_TEXTURE_CTRL_TAG = "texture_picker"; |
84 | LL_TEXTURE_CTRL_TAG("texture_picker"), | 84 | char const* const LL_TEXTURE_VIEW_TAG = "texture_view"; |
85 | LL_TEXTURE_VIEW_TAG("texture_view"), | 85 | char const* const LL_NAME_LIST_CTRL_TAG = "name_list"; |
86 | LL_NAME_LIST_CTRL_TAG("name_list"), | 86 | char const* const LL_STAT_GRAPH_TAG = "stat_graph"; |
87 | LL_STAT_GRAPH_TAG("stat_graph"), | 87 | char const* const LL_DROP_TARGET_TAG = "drop_target"; |
88 | LL_DROP_TARGET_TAG("drop_target"), | 88 | char const* const LL_OVERLAY_BAR_TAG = "overlay_bar"; |
89 | LL_OVERLAY_BAR_TAG("overlay_bar"), | 89 | char const* const LL_NET_MAP_TAG = "net_map"; |
90 | LL_NET_MAP_TAG("net_map"), | 90 | char const* const LL_HUD_VIEW_TAG = "hud_view"; |
91 | LL_HUD_VIEW_TAG("hud_view"), | 91 | char const* const LL_MEMORY_VIEW_TAG = "memory_view"; |
92 | LL_MEMORY_VIEW_TAG("memory_view"), | 92 | char const* const LL_MEDIA_REMOTE_CTRL_TAG = "media_remote"; |
93 | LL_MEDIA_REMOTE_CTRL_TAG("media_remote"), | 93 | char const* const LL_MORPH_VIEW_TAG = "morph_view"; |
94 | LL_MORPH_VIEW_TAG("morph_view"), | 94 | char const* const LL_FRAME_STAT_VIEW_TAG = "frame_stat_view"; |
95 | LL_FRAME_STAT_VIEW_TAG("frame_stat_view"), | 95 | char const* const LL_FOLDER_VIEW_TAG = "folder_view"; |
96 | LL_FOLDER_VIEW_TAG("folder_view"), | 96 | char const* const LL_SNAPSHOT_LIVE_PREVIEW_TAG = "snapshot_preview"; |
97 | LL_SNAPSHOT_LIVE_PREVIEW_TAG("snapshot_preview"), | 97 | char const* const LL_HOVER_VIEW_TAG = "hover_view"; |
98 | LL_HOVER_VIEW_TAG("hover_view"), | 98 | char const* const LL_VELOCITY_BAR_TAG = "velocity_bar"; |
99 | LL_VELOCITY_BAR_TAG("velocity_bar"), | 99 | char const* const LL_PERMISSIONS_VIEW_TAG = "permissions_view"; |
100 | LL_PERMISSIONS_VIEW_TAG("permissions_view"), | 100 | char const* const LL_SCROLLING_PANEL_LIST_TAG = "scrolling_panel_list"; |
101 | LL_SCROLLING_PANEL_LIST_TAG("scrolling_panel_list"), | 101 | char const* const LL_CONTAINER_VIEW_TAG = "container_view"; |
102 | LL_CONTAINER_VIEW_TAG("container_view"), | 102 | char const* const LL_CONSOLE_TAG = "console"; |
103 | LL_CONSOLE_TAG("console"), | 103 | char const* const LL_DEBUG_VIEW_TAG = "debug_view"; |
104 | LL_DEBUG_VIEW_TAG("debug_view"), | 104 | char const* const LL_AUDIOSTATUS_TAG = "audio_status"; |
105 | LL_AUDIOSTATUS_TAG("audio_status"), | 105 | char const* const LL_FAST_TIMER_VIEW_TAG = "fast_timer_view"; |
106 | LL_FAST_TIMER_VIEW_TAG("fast_timer_view"), | 106 | char const* const LL_MENU_ITEM_TEAR_OFF_GL_TAG = "tearoff_menu"; |
107 | LL_MENU_ITEM_TEAR_OFF_GL_TAG("tearoff_menu"), | 107 | char const* const LL_MENU_ITEM_BLANK_GL_TAG = "menu_item_blank"; |
108 | LL_MENU_ITEM_BLANK_GL_TAG("menu_item_blank"), | 108 | char const* const LL_MENU_ITEM_CALL_GL_TAG = "menu_item_call"; |
109 | LL_MENU_ITEM_CALL_GL_TAG("menu_item_call"), | 109 | char const* const LL_MENU_ITEM_CHECK_GL_TAG = "menu_item_check"; |
110 | LL_MENU_ITEM_CHECK_GL_TAG("menu_item_check"), | 110 | char const* const LL_MENU_ITEM_BRANCH_GL_TAG = "menu_item_branch"; |
111 | LL_MENU_ITEM_BRANCH_GL_TAG("menu_item_branch"), | 111 | char const* const LL_MENU_ITEM_BRANCH_DOWN_GL_TAG = "menu_item_branch_down"; |
112 | LL_MENU_ITEM_BRANCH_DOWN_GL_TAG("menu_item_branch_down"), | 112 | char const* const LL_PIE_MENU_BRANCH_TAG = "pie_menu_branch"; |
113 | LL_PIE_MENU_BRANCH_TAG("pie_menu_branch"), | 113 | char const* const LL_PIE_MENU_TAG = "pie_menu"; |
114 | LL_PIE_MENU_TAG("pie_menu"), | 114 | char const* const LL_MENU_ITEM_SEPARATOR_GL_TAG = "menu_item_separator"; |
115 | LL_MENU_ITEM_SEPARATOR_GL_TAG("menu_item_separator"), | 115 | char const* const LL_MENU_ITEM_VERTICAL_SEPARATOR_GL_TAG = "menu_item_vertical_separator"; |
116 | LL_MENU_ITEM_VERTICAL_SEPARATOR_GL_TAG("menu_item_vertical_separator"), | 116 | char const* const LL_ROOT_VIEW_TAG = "root_view"; |
117 | LL_ROOT_VIEW_TAG("root_view"), | 117 | char const* const LL_FOLDER_VIEW_ITEM_TAG = "folder_item"; |
118 | LL_FOLDER_VIEW_ITEM_TAG("folder_item"), | 118 | char const* const LL_FOLDER_VIEW_FOLDER_TAG = "folder"; |
119 | LL_FOLDER_VIEW_FOLDER_TAG("folder"), | 119 | char const* const LL_TEXTURE_BAR_TAG = "texture_bar"; |
120 | LL_TEXTURE_BAR_TAG("texture_bar"), | 120 | char const* const LL_JOYSTICK_SLIDE = "joystick_slide"; |
121 | LL_JOYSTICK_SLIDE("joystick_slide"), | 121 | char const* const LL_JOYSTICK_TURN = "joystick_turn"; |
122 | LL_JOYSTICK_TURN("joystick_turn"), | 122 | char const* const LL_GROUP_DROP_TARGET_TAG = "group_drop_target"; |
123 | LL_GROUP_DROP_TARGET_TAG("group_drop_target"), | 123 | char const* const LL_LAYOUT_STACK_TAG = "layout_stack"; |
124 | LL_LAYOUT_STACK_TAG("layout_stack"), | 124 | char const* const LL_LAYOUT_PANEL_TAG = "layout_panel"; |
125 | LL_LAYOUT_PANEL_TAG("layout_panel"), | 125 | char const* const LL_FLYOUT_BUTTON_TAG = "flyout_button"; |
126 | LL_FLYOUT_BUTTON_TAG("flyout_button"), | 126 | char const* const LL_FLYOUT_BUTTON_ITEM_TAG = "flyout_button_item"; |
127 | LL_FLYOUT_BUTTON_ITEM_TAG("flyout_button_item"), | 127 | char const* const LL_SIMPLE_TEXT_EDITOR_TAG = "simple_text_editor"; |
128 | LL_SIMPLE_TEXT_EDITOR_TAG("simple_text_editor"), | 128 | char const* const LL_RADIO_ITEM_TAG = "radio_item"; |
129 | LL_RADIO_ITEM_TAG("radio_item"), | 129 | char const* const LL_PROGRESS_BAR_TAG = "progress_bar"; |
130 | LL_PROGRESS_BAR_TAG("progress_bar"); | 130 | |
131 | #endif | 131 | #endif |
diff --git a/linden/indra/llui/llview.cpp b/linden/indra/llui/llview.cpp index 8de376f..507c5f5 100644 --- a/linden/indra/llui/llview.cpp +++ b/linden/indra/llui/llview.cpp | |||
@@ -136,11 +136,6 @@ LLView::~LLView() | |||
136 | { | 136 | { |
137 | //llinfos << "Deleting view " << mName << ":" << (void*) this << llendl; | 137 | //llinfos << "Deleting view " << mName << ":" << (void*) this << llendl; |
138 | // llassert(LLView::sIsDrawing == FALSE); | 138 | // llassert(LLView::sIsDrawing == FALSE); |
139 | if( gFocusMgr.getKeyboardFocus() == this ) | ||
140 | { | ||
141 | llwarns << "View holding keyboard focus deleted: " << getName() << ". Keyboard focus removed." << llendl; | ||
142 | gFocusMgr.removeKeyboardFocusWithoutCallback( this ); | ||
143 | } | ||
144 | 139 | ||
145 | if( hasMouseCapture() ) | 140 | if( hasMouseCapture() ) |
146 | { | 141 | { |
@@ -965,6 +960,19 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks) | |||
965 | return handled; | 960 | return handled; |
966 | } | 961 | } |
967 | 962 | ||
963 | BOOL LLView::handleHScrollWheel(S32 x, S32 y, S32 clicks) | ||
964 | { | ||
965 | BOOL handled = FALSE; | ||
966 | if( getVisible() && getEnabled() ) | ||
967 | { | ||
968 | handled = childrenHandleHScrollWheel( x, y, clicks ) != NULL; | ||
969 | if( !handled && blockMouseEvent(x, y) ) | ||
970 | { | ||
971 | handled = TRUE; | ||
972 | } | ||
973 | } | ||
974 | return handled; | ||
975 | } | ||
968 | BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) | 976 | BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) |
969 | { | 977 | { |
970 | BOOL handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; | 978 | BOOL handled = childrenHandleRightMouseDown( x, y, mask ) != NULL; |
@@ -1037,6 +1045,34 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) | |||
1037 | return handled_view; | 1045 | return handled_view; |
1038 | } | 1046 | } |
1039 | 1047 | ||
1048 | LLView* LLView::childrenHandleHScrollWheel(S32 x, S32 y, S32 clicks) | ||
1049 | { | ||
1050 | LLView* handled_view = NULL; | ||
1051 | if (getVisible() && getEnabled() ) | ||
1052 | { | ||
1053 | for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) | ||
1054 | { | ||
1055 | LLView* viewp = *child_it; | ||
1056 | S32 local_x = x - viewp->getRect().mLeft; | ||
1057 | S32 local_y = y - viewp->getRect().mBottom; | ||
1058 | if (viewp->pointInView(local_x, local_y) | ||
1059 | && viewp->getVisible() | ||
1060 | && viewp->getEnabled() | ||
1061 | && viewp->handleHScrollWheel( local_x, local_y, clicks )) | ||
1062 | { | ||
1063 | if (sDebugMouseHandling) | ||
1064 | { | ||
1065 | sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage; | ||
1066 | } | ||
1067 | |||
1068 | handled_view = viewp; | ||
1069 | break; | ||
1070 | } | ||
1071 | } | ||
1072 | } | ||
1073 | return handled_view; | ||
1074 | } | ||
1075 | |||
1040 | LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask) | 1076 | LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask) |
1041 | { | 1077 | { |
1042 | LLView* handled_view = NULL; | 1078 | LLView* handled_view = NULL; |
@@ -1327,7 +1363,7 @@ void LLView::draw() | |||
1327 | LLRect screenRect; | 1363 | LLRect screenRect; |
1328 | 1364 | ||
1329 | // draw focused control on top of everything else | 1365 | // draw focused control on top of everything else |
1330 | LLView* focus_view = gFocusMgr.getKeyboardFocus(); | 1366 | LLUICtrl* focus_view = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); |
1331 | if (focus_view && focus_view->getParent() != this) | 1367 | if (focus_view && focus_view->getParent() != this) |
1332 | { | 1368 | { |
1333 | focus_view = NULL; | 1369 | focus_view = NULL; |
@@ -1547,7 +1583,7 @@ void LLView::updateBoundingRect() | |||
1547 | 1583 | ||
1548 | LLRect child_bounding_rect = childp->getBoundingRect(); | 1584 | LLRect child_bounding_rect = childp->getBoundingRect(); |
1549 | 1585 | ||
1550 | if (local_bounding_rect.isNull()) | 1586 | if (local_bounding_rect.isEmpty()) |
1551 | { | 1587 | { |
1552 | // start out with bounding rect equal to first visible child's bounding rect | 1588 | // start out with bounding rect equal to first visible child's bounding rect |
1553 | local_bounding_rect = child_bounding_rect; | 1589 | local_bounding_rect = child_bounding_rect; |
@@ -1555,7 +1591,7 @@ void LLView::updateBoundingRect() | |||
1555 | else | 1591 | else |
1556 | { | 1592 | { |
1557 | // accumulate non-null children rectangles | 1593 | // accumulate non-null children rectangles |
1558 | if (!child_bounding_rect.isNull()) | 1594 | if (!child_bounding_rect.isEmpty()) |
1559 | { | 1595 | { |
1560 | local_bounding_rect.unionWith(child_bounding_rect); | 1596 | local_bounding_rect.unionWith(child_bounding_rect); |
1561 | } | 1597 | } |
diff --git a/linden/indra/llui/llview.h b/linden/indra/llui/llview.h index 7e09dfa..9243f4f 100644 --- a/linden/indra/llui/llview.h +++ b/linden/indra/llui/llview.h | |||
@@ -53,6 +53,7 @@ | |||
53 | #include "stdenums.h" | 53 | #include "stdenums.h" |
54 | #include "lluistring.h" | 54 | #include "lluistring.h" |
55 | #include "llcursortypes.h" | 55 | #include "llcursortypes.h" |
56 | #include "llfocusmgr.h" | ||
56 | 57 | ||
57 | const U32 FOLLOWS_NONE = 0x00; | 58 | const U32 FOLLOWS_NONE = 0x00; |
58 | const U32 FOLLOWS_LEFT = 0x01; | 59 | const U32 FOLLOWS_LEFT = 0x01; |
@@ -207,7 +208,7 @@ public: | |||
207 | } | 208 | } |
208 | }; | 209 | }; |
209 | 210 | ||
210 | class LLView : public LLMouseHandler, public LLMortician | 211 | class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElement |
211 | { | 212 | { |
212 | 213 | ||
213 | public: | 214 | public: |
@@ -398,9 +399,11 @@ public: | |||
398 | virtual BOOL canSnapTo(const LLView* other_view); | 399 | virtual BOOL canSnapTo(const LLView* other_view); |
399 | 400 | ||
400 | virtual void snappedTo(const LLView* snap_view); | 401 | virtual void snappedTo(const LLView* snap_view); |
402 | |||
403 | // inherited from LLFocusableElement | ||
404 | /* virtual */ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); | ||
405 | /* virtual */ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); | ||
401 | 406 | ||
402 | virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); | ||
403 | virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); | ||
404 | virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, | 407 | virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, |
405 | EDragAndDropType cargo_type, | 408 | EDragAndDropType cargo_type, |
406 | void* cargo_data, | 409 | void* cargo_data, |
@@ -421,8 +424,9 @@ public: | |||
421 | BOOL getSaveToXML() const { return mSaveToXML; } | 424 | BOOL getSaveToXML() const { return mSaveToXML; } |
422 | void setSaveToXML(BOOL b) { mSaveToXML = b; } | 425 | void setSaveToXML(BOOL b) { mSaveToXML = b; } |
423 | 426 | ||
424 | virtual void onFocusLost(); | 427 | // inherited from LLFocusableElement |
425 | virtual void onFocusReceived(); | 428 | /* virtual */ void onFocusLost(); |
429 | /* virtual */ void onFocusReceived(); | ||
426 | 430 | ||
427 | typedef enum e_hit_test_type | 431 | typedef enum e_hit_test_type |
428 | { | 432 | { |
@@ -469,6 +473,7 @@ public: | |||
469 | /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); | 473 | /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); |
470 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); | 474 | /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); |
471 | /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); | 475 | /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); |
476 | /*virtual*/ BOOL handleHScrollWheel(S32 x, S32 y, S32 clicks); | ||
472 | /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); | 477 | /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); |
473 | /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); | 478 | /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); |
474 | /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); // Display mToolTipMsg if no child handles it. | 479 | /*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); // Display mToolTipMsg if no child handles it. |
@@ -609,6 +614,7 @@ protected: | |||
609 | LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask); | 614 | LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask); |
610 | LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); | 615 | LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); |
611 | LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); | 616 | LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); |
617 | LLView* childrenHandleHScrollWheel(S32 x, S32 y, S32 clicks); | ||
612 | LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); | 618 | LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); |
613 | LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); | 619 | LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); |
614 | 620 | ||