Merge inspectors UI project, gooey-4, into viewer-2 trunk. Added new tooltips to 3D avatars, 2D avatar names, and 3D objects. Refactors tooltips and text boxes, line editors, and text editors. Breaks LLExpandableTextBox, but a fix is coming.

Resolved conflicts in lltexteditor.cpp, llchatitemscontainerctrl.cpp, llchatmsgbox.cpp, llfloaterbuycurrency.cpp, llnearbychat.cpp, floater_buy_currency.xml, and ru/strings.xml

Merging revisions 134925-135157 of svn+ssh://svn.lindenlab.com/svn/linden/branches/gooey/gooey-4 into C:\source\viewer-2.0.0-3, respecting ancestry
master
James Cook 2009-10-03 23:40:28 +00:00
parent b1a280841e
commit ada0f4fa22
241 changed files with 6890 additions and 5338 deletions

View File

@ -37,6 +37,7 @@
#include "llcombobox.h"
#include "llcontainerview.h"
#include "lliconctrl.h"
#include "llmenubutton.h"
#include "llmenugl.h"
#include "llmultislider.h"
#include "llmultisliderctrl.h"
@ -64,6 +65,7 @@ void LLWidgetReg::initClass(bool register_widgets)
if (register_widgets)
{
LLDefaultChildRegistry::Register<LLButton> button("button");
LLDefaultChildRegistry::Register<LLMenuButton> menu_button("menu_button");
LLDefaultChildRegistry::Register<LLCheckBoxCtrl> check_box("check_box");
LLDefaultChildRegistry::Register<LLComboBox> combo_box("combo_box");
LLDefaultChildRegistry::Register<LLFilterEditor> filter_editor("filter_editor");

View File

@ -117,7 +117,9 @@ using snprintf_hack::snprintf;
#if defined(LL_WINDOWS)
#define BOOST_REGEX_NO_LIB 1
#define CURL_STATICLIB 1
#ifndef XML_STATIC
#define XML_STATIC
#endif
#endif // LL_WINDOWS

View File

@ -77,6 +77,7 @@ public:
Type* operator->() { return nonNull(mPointer); }
Type* get() const { return mPointer; }
void clear() { assign(NULL); }
// we disallow these operations as they expose our null objects to direct manipulation
// and bypass the reference counting semantics
//const Type& operator*() const { return *nonNull(mPointer); }

View File

@ -34,7 +34,7 @@
#include "llsecondlifeurls.h"
/*
const std::string CREATE_ACCOUNT_URL (
"http://secondlife.com/registration/");
"http://join.secondlife.com/");
const std::string MANAGE_ACCOUNT (
"http://secondlife.com/account/"); // *TODO: NOT USED

View File

@ -38,6 +38,23 @@
LLStringTable gStringTable(32768);
LLStringTableEntry::LLStringTableEntry(const char *str)
: mString(NULL), mCount(1)
{
// Copy string
U32 length = (U32)strlen(str) + 1; /*Flawfinder: ignore*/
length = llmin(length, MAX_STRINGS_LENGTH);
mString = new char[length];
strncpy(mString, str, length); /*Flawfinder: ignore*/
mString[length - 1] = 0;
}
LLStringTableEntry::~LLStringTableEntry()
{
delete [] mString;
mCount = 0;
}
LLStringTable::LLStringTable(int tablesize)
: mUniqueEntries(0)
{

View File

@ -59,21 +59,9 @@ const U32 MAX_STRINGS_LENGTH = 256;
class LLStringTableEntry
{
public:
LLStringTableEntry(const char *str)
: mString(NULL), mCount(1)
{
// Copy string
U32 length = (U32)strlen(str) + 1; /*Flawfinder: ignore*/
length = llmin(length, MAX_STRINGS_LENGTH);
mString = new char[length];
strncpy(mString, str, length); /*Flawfinder: ignore*/
mString[length - 1] = 0;
}
~LLStringTableEntry()
{
delete [] mString;
mCount = 0;
}
LLStringTableEntry(const char *str);
~LLStringTableEntry();
void incCount() { mCount++; }
BOOL decCount() { return --mCount; }

View File

@ -38,6 +38,6 @@ const S32 LL_VERSION_MINOR = 0;
const S32 LL_VERSION_PATCH = 0;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life 2009";
const char * const LL_CHANNEL = "Second Life Developer";
#endif

View File

@ -484,7 +484,8 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
S32 start_of_last_word = 0;
BOOL in_word = FALSE;
F32 scaled_max_pixels = (F32)llceil(max_pixels * sScaleX);
// avoid S32 overflow when max_pixels == S32_MAX by staying in floating point
F32 scaled_max_pixels = ceil(max_pixels * sScaleX);
S32 i;
for (i=0; (i < max_chars); i++)

View File

@ -51,6 +51,7 @@ set(llui_SOURCE_FILES
lllayoutstack.cpp
lllineeditor.cpp
lllocalcliprect.cpp
llmenubutton.cpp
llmenugl.cpp
llmodaldialog.cpp
llmultifloater.cpp
@ -87,6 +88,7 @@ set(llui_SOURCE_FILES
lltextparser.cpp
lltransientfloatermgr.cpp
lltransutil.cpp
lltoggleablemenu.cpp
lltooltip.cpp
llui.cpp
lluicolortable.cpp
@ -137,6 +139,7 @@ set(llui_HEADER_FILES
lllazyvalue.h
lllineeditor.h
lllocalcliprect.h
llmenubutton.h
llmenugl.h
llmodaldialog.h
llmultifloater.h
@ -171,6 +174,7 @@ set(llui_HEADER_FILES
lltextbox.h
lltexteditor.h
lltextparser.h
lltoggleablemenu.h
lltooltip.h
lltransientfloatermgr.h
lltransutil.h

View File

@ -145,7 +145,8 @@ LLButton::LLButton(const LLButton::Params& p)
mRightHPad(p.pad_right),
mHoverGlowStrength(p.hover_glow_amount),
mCommitOnReturn(p.commit_on_return),
mFadeWhenDisabled(FALSE)
mFadeWhenDisabled(FALSE),
mForcePressedState(FALSE)
{
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
@ -536,7 +537,8 @@ void LLButton::draw()
bool enabled = isInEnabledChain();
bool pressed = pressed_by_keyboard
|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y));
|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y))
|| mForcePressedState;
bool selected = getToggleState();
bool use_glow_effect = FALSE;

View File

@ -233,6 +233,8 @@ public:
static void toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);
static void setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);
static void showHelp(LLUICtrl* ctrl, const LLSD& sdname);
void setForcePressedState(BOOL b) { mForcePressedState = b; }
protected:
const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; }
@ -310,6 +312,7 @@ private:
BOOL mNeedsHighlight;
BOOL mCommitOnReturn;
BOOL mFadeWhenDisabled;
BOOL mForcePressedState;
LLFrameTimer mFlashingTimer;
};

View File

@ -97,7 +97,7 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
LLTextBox::Params tbparams = p.label_text;
tbparams.rect(label_rect);
tbparams.text(local_label);
tbparams.initial_value(local_label);
if (p.font.isProvided())
{
tbparams.font(p.font);

View File

@ -714,11 +714,11 @@ void LLComboBox::onItemSelected(const LLSD& data)
}
}
BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
BOOL LLComboBox::handleToolTip(S32 x, S32 y, MASK mask)
{
std::string tool_tip;
if(LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen))
if(LLUICtrl::handleToolTip(x, y, mask))
{
return TRUE;
}
@ -731,7 +731,7 @@ BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_re
if( !tool_tip.empty() )
{
LLToolTipMgr::instance().show(LLToolTipParams()
LLToolTipMgr::instance().show(LLToolTip::Params()
.message(tool_tip)
.sticky_rect(calcScreenRect()));
}

View File

@ -113,7 +113,7 @@ public:
// LLView interface
virtual void onFocusLost();
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);

View File

@ -61,7 +61,7 @@ const F32 FADE_DURATION = 2.f;
const S32 MIN_CONSOLE_WIDTH = 200;
LLConsole::LLConsole(const LLConsole::Params& p)
: LLView(p),
: LLUICtrl(p),
LLFixedBuffer(p.max_lines),
mLinePersistTime(p.persist_time), // seconds
mFont(p.font)
@ -94,7 +94,7 @@ void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent)
mConsoleWidth = new_width;
mConsoleHeight= new_height;
LLView::reshape(new_width, new_height, called_from_parent);
LLUICtrl::reshape(new_width, new_height, called_from_parent);
for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++)
{

View File

@ -34,14 +34,13 @@
#define LL_LLCONSOLE_H
#include "llfixedbuffer.h"
#include "llview.h"
#include "lluictrl.h"
#include "v4color.h"
#include <deque>
class LLFontGL;
class LLSD;
class LLConsole : public LLFixedBuffer, public LLView
class LLConsole : public LLFixedBuffer, public LLUICtrl
{
public:
typedef enum e_font_size
@ -51,7 +50,7 @@ public:
BIG = 1
} EFontSize;
struct Params : public LLInitParam::Block<Params, LLView::Params>
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<U32> max_lines;
Optional<F32> persist_time;

View File

@ -108,7 +108,7 @@ void LLDragHandleTop::setTitle(const std::string& title)
LLTextBox::Params params;
params.name("Drag Handle Title");
params.rect(getRect());
params.text(trimmed_title);
params.initial_value(trimmed_title);
params.font(font);
params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
params.font_shadow(LLFontGL::DROP_SHADOW_SOFT);
@ -120,7 +120,7 @@ void LLDragHandleTop::setTitle(const std::string& title)
}
const std::string& LLDragHandleTop::getTitle() const
std::string LLDragHandleTop::getTitle() const
{
return mTitleBox == NULL ? LLStringUtil::null : mTitleBox->getText();
}
@ -138,7 +138,7 @@ void LLDragHandleLeft::setTitle(const std::string& )
}
const std::string& LLDragHandleLeft::getTitle() const
std::string LLDragHandleLeft::getTitle() const
{
return LLStringUtil::null;
}
@ -256,7 +256,8 @@ void LLDragHandleTop::reshapeTitleBox()
getRect().getWidth() - LEFT_PAD - RIGHT_PAD,
title_height);
mTitleBox->setRect( title_rect );
// calls reshape on mTitleBox
mTitleBox->setShape( title_rect );
}
void LLDragHandleTop::reshape(S32 width, S32 height, BOOL called_from_parent)

View File

@ -74,7 +74,7 @@ public:
void setTitleVisible(BOOL visible);
virtual void setTitle( const std::string& title ) = 0;
virtual const std::string& getTitle() const = 0;
virtual std::string getTitle() const = 0;
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
@ -112,7 +112,7 @@ protected:
friend class LLUICtrlFactory;
public:
virtual void setTitle( const std::string& title );
virtual const std::string& getTitle() const;
virtual std::string getTitle() const;
virtual void draw();
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
@ -130,7 +130,7 @@ protected:
friend class LLUICtrlFactory;
public:
virtual void setTitle( const std::string& title );
virtual const std::string& getTitle() const;
virtual std::string getTitle() const;
virtual void draw();
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);

View File

@ -785,7 +785,7 @@ void LLFloater::applyTitle()
}
}
const std::string& LLFloater::getCurrentTitle() const
std::string LLFloater::getCurrentTitle() const
{
return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null;
}

View File

@ -171,7 +171,7 @@ public:
LLMultiFloater* getHost();
void applyTitle();
const std::string& getCurrentTitle() const;
std::string getCurrentTitle() const;
void setTitle( const std::string& title);
std::string getTitle() const;
void setShortTitle( const std::string& short_title );

View File

@ -274,7 +274,7 @@ BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const
// Returns TRUE is parent or any descedent of parent is the mouse captor.
BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const
{
if( mMouseCaptor && mMouseCaptor->isView() )
if( mMouseCaptor && dynamic_cast<LLView*>(mMouseCaptor) != NULL )
{
LLView* captor_view = (LLView*)mMouseCaptor;
while( captor_view )

View File

@ -35,7 +35,9 @@
#include "linden_common.h"
#include "lllayoutstack.h"
#include "lllocalcliprect.h"
#include "llpanel.h"
#include "llresizebar.h"
#include "llcriticaldamp.h"

View File

@ -34,7 +34,9 @@
#ifndef LL_LLLAYOUTSTACK_H
#define LL_LLLAYOUTSTACK_H
#include "llpanel.h"
#include "llview.h"
class LLPanel;
class LLLayoutStack : public LLView
{

View File

@ -107,9 +107,6 @@ LLLineEditor::Params::Params()
highlight_color("highlight_color"),
preedit_bg_color("preedit_bg_color"),
border(""),
is_unicode("is_unicode"),
drop_shadow_visible("drop_shadow_visible"),
border_drop_shadow_visible("border_drop_shadow_visible"),
bg_visible("bg_visible"),
text_pad_left("text_pad_left"),
text_pad_right("text_pad_right"),
@ -544,18 +541,13 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
return TRUE;
}
if (mSelectAllonFocusReceived
&& gFocusMgr.getKeyboardFocus() != this)
{
setFocus( TRUE );
}
else
if (!mSelectAllonFocusReceived
|| gFocusMgr.getKeyboardFocus() == this)
{
mLastSelectionStart = -1;
mLastSelectionStart = -1;
setFocus( TRUE );
if (mask & MASK_SHIFT)
{
// Handle selection extension
@ -621,6 +613,8 @@ BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
gFocusMgr.setMouseCapture( this );
}
setFocus(TRUE);
// delay cursor flashing
mKeystrokeTimer.reset();

View File

@ -105,10 +105,7 @@ public:
Optional<S32> text_pad_left,
text_pad_right;
Ignored is_unicode,
drop_shadow_visible,
border_drop_shadow_visible,
bg_visible;
Ignored bg_visible;
Params();
};
@ -280,6 +277,7 @@ private:
virtual void getPreeditRange(S32 *position, S32 *length) const;
virtual BOOL getPreeditLocation(S32 query_position, LLCoordGL *coord, LLRect *bounds, LLRect *control) const;
virtual S32 getPreeditFontSize() const;
virtual LLWString getPreeditString() const { return getWText(); }
protected:
LLUIString mText; // The string being edited.

135
indra/llui/llmenubutton.cpp Normal file
View File

@ -0,0 +1,135 @@
/**
* @file llbutton.cpp
* @brief LLButton base class
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llmenubutton.h"
// Linden library includes
#include "llmenugl.h"
#include "llstring.h"
#include "v4color.h"
static LLDefaultChildRegistry::Register<LLMenuButton> r("menu_button");
LLMenuButton::Params::Params()
: menu_filename("menu_filename")
{
}
LLMenuButton::LLMenuButton(const LLMenuButton::Params& p)
: LLButton(p),
mMenu(NULL),
mMenuVisibleLastFrame(false)
{
std::string menu_filename = p.menu_filename;
if (!menu_filename.empty())
{
mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (!mMenu)
{
llwarns << "Error loading menu_button menu" << llendl;
}
}
}
void LLMenuButton::toggleMenu()
{
if(!mMenu)
return;
if (mMenu->getVisible() || mMenuVisibleLastFrame)
{
mMenu->setVisible(FALSE);
}
else
{
LLRect rect = getRect();
//mMenu->needsArrange(); //so it recalculates the visible elements
LLMenuGL::showPopup(getParent(), mMenu, rect.mLeft, rect.mBottom);
}
}
BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
{
if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
{
toggleMenu();
return TRUE;
}
if (mMenu && mMenu->getVisible() && key == KEY_ESCAPE && mask == MASK_NONE)
{
mMenu->setVisible(FALSE);
return TRUE;
}
return FALSE;
}
BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (hasTabStop() && !getIsChrome())
{
setFocus(TRUE);
}
toggleMenu();
if (getSoundFlags() & MOUSE_DOWN)
{
make_ui_sound("UISndClick");
}
return TRUE;
}
void LLMenuButton::draw()
{
//we save this off so next frame when we try to close it by
//button click, and it hides menus before we get to it, we know
mMenuVisibleLastFrame = mMenu && mMenu->getVisible();
if (mMenuVisibleLastFrame)
{
setForcePressedState(TRUE);
}
LLButton::draw();
setForcePressedState(FALSE);
}

68
indra/llui/llmenubutton.h Normal file
View File

@ -0,0 +1,68 @@
/**
* @file llbutton.h
* @brief Header for buttons
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLMENUBUTTON_H
#define LL_LLMENUBUTTON_H
#include "llbutton.h"
class LLMenuGL;
class LLMenuButton
: public LLButton
{
public:
struct Params
: public LLInitParam::Block<Params, LLButton::Params>
{
// filename for it's toggleable menu
Optional<std::string> menu_filename;
Params();
};
void toggleMenu();
/*virtual*/ void draw();
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
protected:
friend class LLUICtrlFactory;
LLMenuButton(const Params&);
private:
LLMenuGL* mMenu;
bool mMenuVisibleLastFrame;
};
#endif // LL_LLMENUBUTTON_H

View File

@ -781,6 +781,10 @@ LLMenuItemCallGL::LLMenuItemCallGL(const LLMenuItemCallGL::Params& p)
void LLMenuItemCallGL::initFromParams(const Params& p)
{
if (p.on_visible.isProvided())
{
initVisibleCallback(p.on_visible, mVisibleSignal);
}
if (p.on_enable.isProvided())
{
initEnableCallback(p.on_enable, mEnableSignal);
@ -823,9 +827,19 @@ void LLMenuItemCallGL::updateEnabled( void )
}
}
void LLMenuItemCallGL::updateVisible( void )
{
if (mVisibleSignal.num_slots() > 0)
{
bool visible = mVisibleSignal(this, LLSD());
setVisible(visible);
}
}
void LLMenuItemCallGL::buildDrawLabel( void )
{
updateEnabled();
updateVisible();
LLMenuItemGL::buildDrawLabel();
}
@ -1224,23 +1238,7 @@ void LLMenuItemBranchGL::openMenu()
rect.translate(0, TEAROFF_SEPARATOR_HEIGHT_PIXELS);
}
branch->setRect( rect );
S32 x = 0;
S32 y = 0;
branch->localPointToOtherView( 0, 0, &x, &y, branch->getParent() );
S32 delta_x = 0;
S32 delta_y = 0;
if( y < menu_region_rect.mBottom )
{
delta_y = menu_region_rect.mBottom - y;
}
S32 menu_region_width = menu_region_rect.getWidth();
if( x - menu_region_rect.mLeft > menu_region_width - rect.getWidth() )
{
// move sub-menu over to left side
delta_x = llmax(-x, (-1 * (rect.getWidth() + getRect().getWidth())));
}
branch->translate( delta_x, delta_y );
branch->translateIntoRectWithExclusion( menu_region_rect, getMenu()->getRect(), FALSE );
branch->setVisible( TRUE );
branch->getParent()->sendChildToFront(branch);
@ -1935,6 +1933,9 @@ void LLMenuGL::arrange( void )
item_list_t::iterator item_iter;
for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
{
// do first so LLMenuGLItemCall can call on_visible to determine if visible
(*item_iter)->buildDrawLabel();
if ((*item_iter)->getVisible())
{
if (!getTornOff()
@ -1976,6 +1977,9 @@ void LLMenuGL::arrange( void )
for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
{
// do first so LLMenuGLItemCall can call on_visible to determine if visible
(*item_iter)->buildDrawLabel();
if ((*item_iter)->getVisible())
{
if (!getTornOff()
@ -2162,7 +2166,7 @@ void LLMenuGL::arrange( void )
item_list_t::iterator item_iter;
for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
{
{
if ((*item_iter)->getVisible())
{
if (mScrollable)
@ -2193,7 +2197,6 @@ void LLMenuGL::arrange( void )
}
}
(*item_iter)->setRect( rect );
(*item_iter)->buildDrawLabel();
}
}
}
@ -2936,11 +2939,27 @@ void hide_top_view( LLView* view )
// static
void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
{
const S32 CURSOR_HEIGHT = 22; // Approximate "normal" cursor size
const S32 CURSOR_WIDTH = 12;
// Save click point for detecting cursor moves before mouse-up.
// Must be in local coords to compare with mouseUp events.
// If the mouse doesn't move, the menu will stay open ala the Mac.
// See also LLContextMenu::show()
S32 mouse_x, mouse_y;
// Resetting scrolling position
if (menu->isScrollable())
{
menu->mFirstVisibleItem = NULL;
}
menu->setVisible( TRUE );
// Fix menu rect if needed.
menu->needsArrange();
menu->arrangeAndClear();
LLUI::getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y);
LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);
@ -2948,7 +2967,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
const S32 HPAD = 2;
LLRect rect = menu->getRect();
//LLView* cur_view = spawning_view;
S32 left = x + HPAD;
S32 top = y;
spawning_view->localPointToOtherView(left, top, &left, &top, menu->getParent());
@ -2956,37 +2974,19 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
rect.getWidth(), rect.getHeight() );
menu->setRect( rect );
// Resetting scrolling position
if (menu->isScrollable())
{
menu->mFirstVisibleItem = NULL;
menu->needsArrange();
}
menu->arrangeAndClear(); // Fix menu rect if needed.
rect = menu->getRect();
// Adjust context menu to fit onscreen
S32 bottom;
left = rect.mLeft;
bottom = rect.mBottom;
S32 delta_x = 0;
S32 delta_y = 0;
if( bottom < menu_region_rect.mBottom )
{
// At this point, we need to move the context menu to the
// other side of the mouse.
delta_y = (rect.getHeight() + 2 * HPAD);
}
if( left > menu_region_rect.mRight - rect.getWidth() )
{
// At this point, we need to move the context menu to the
// other side of the mouse.
delta_x = -(rect.getWidth() + 2 * HPAD);
}
menu->translate( delta_x, delta_y );
menu->setVisible( TRUE );
LLRect mouse_rect;
const S32 MOUSE_CURSOR_PADDING = 5;
mouse_rect.setLeftTopAndSize(mouse_x - MOUSE_CURSOR_PADDING,
mouse_y + MOUSE_CURSOR_PADDING,
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect, FALSE );
menu->getParent()->sendChildToFront(menu);
}
///============================================================================

View File

@ -268,15 +268,18 @@ public:
{
Optional<EnableCallbackParam > on_enable;
Optional<CommitCallbackParam > on_click;
Optional<VisibleCallbackParam > on_visible;
Params()
: on_enable("on_enable"),
on_click("on_click")
on_click("on_click"),
on_visible("on_visible")
{}
};
protected:
LLMenuItemCallGL(const Params&);
friend class LLUICtrlFactory;
void updateEnabled( void );
void updateVisible( void );
public:
void initFromParams(const Params& p);
@ -300,10 +303,15 @@ public:
{
return mEnableSignal.connect(cb);
}
boost::signals2::connection setVisibleCallback( const visible_signal_t::slot_type& cb )
{
return mVisibleSignal.connect(cb);
}
private:
enable_signal_t mEnableSignal;
visible_signal_t mVisibleSignal;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -98,7 +98,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p)
LLTextBox::Params params;
params.name("MultiSliderCtrl Label");
params.rect(label_rect);
params.text(p.label);
params.initial_value(p.label());
params.font(p.font);
mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mLabelBox);

View File

@ -819,15 +819,6 @@ void LLPanel::childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWS
}
}
void LLPanel::childSetWrappedText(const std::string& id, const std::string& text, bool visible)
{
LLTextBox* child = findChild<LLTextBox>(id);
if (child)
{
child->setVisible(visible);
child->setWrappedText(text);
}
}
void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> function, void* value)
{

View File

@ -209,9 +209,6 @@ public:
void childShowTab(const std::string& id, const std::string& tabname, bool visible = true);
LLPanel *childGetVisibleTab(const std::string& id) const;
// LLTextBox
void childSetWrappedText(const std::string& id, const std::string& text, bool visible = true);
// LLTextBox/LLTextEditor/LLLineEditor
void childSetText(const std::string& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); }
@ -243,7 +240,8 @@ protected:
LLCallbackMap::map_t mFactoryMap;
CommitCallbackRegistry::ScopedRegistrar mCommitCallbackRegistrar;
EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
VisibleCallbackRegistry::ScopedRegistrar mVisibleCallbackRegistrar;
commit_signal_t mVisibleSignal; // Called when visibility changes, passes new visibility as LLSD()
std::string mHelpTopic; // the name of this panel's help topic to display in the Help Viewer

View File

@ -55,6 +55,8 @@ LLRadioGroup::Params::Params()
name = "radio_group";
mouse_opaque = true;
follows.flags = FOLLOWS_LEFT | FOLLOWS_TOP;
// radio items are not tabbable until they are selected
tab_stop = false;
}
LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p)

View File

@ -47,18 +47,7 @@ class LLRadioCtrl : public LLCheckBoxCtrl
{
public:
struct Params : public LLInitParam::Block<Params, LLCheckBoxCtrl::Params>
{
Ignored length;
Ignored type;
Params()
: length("length"),
type("type")
{
// radio items are not tabbable until they are selected
tab_stop = false;
}
};
{};
/*virtual*/ ~LLRadioCtrl();
/*virtual*/ void setValue(const LLSD& value);

View File

@ -88,8 +88,6 @@ LLScrollbar::LLScrollbar(const Params & p)
mCurGlowStrength(0.f),
mTrackColor( p.track_color() ),
mThumbColor ( p.thumb_color() ),
mOnScrollEndCallback( NULL ),
mOnScrollEndData( NULL ),
mThumbImageV(p.thumb_image_vertical),
mThumbImageH(p.thumb_image_horizontal),
mTrackImageV(p.track_image_vertical),
@ -243,11 +241,6 @@ void LLScrollbar::updateThumbRect()
mThumbRect.mRight = thumb_start + thumb_length;
mThumbRect.mBottom = 0;
}
if (mOnScrollEndCallback && mOnScrollEndData && (mDocPos == getDocPosMax()))
{
mOnScrollEndCallback(mOnScrollEndData);
}
}
BOOL LLScrollbar::handleMouseDown(S32 x, S32 y, MASK mask)
@ -568,12 +561,6 @@ void LLScrollbar::draw()
}
}
BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax());
if (mOnScrollEndCallback && was_scrolled_to_bottom)
{
mOnScrollEndCallback(mOnScrollEndData);
}
// Draw children
LLView::draw();
} // end draw

View File

@ -164,9 +164,6 @@ private:
LLUIImagePtr mTrackImageH;
S32 mThickness;
void (*mOnScrollEndCallback)(void*);
void *mOnScrollEndData;
};

View File

@ -76,6 +76,7 @@ LLScrollContainer::Params::Params()
: is_opaque("opaque"),
bg_color("color"),
border_visible("border_visible"),
hide_scrollbar("hide_scrollbar"),
min_auto_scroll_rate("min_auto_scroll_rate", 100),
max_auto_scroll_rate("max_auto_scroll_rate", 1000),
reserve_scroll_corner("reserve_scroll_corner", false)
@ -93,6 +94,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
mAutoScrollRate( 0.f ),
mBackgroundColor(p.bg_color()),
mIsOpaque(p.is_opaque),
mHideScrollbar(p.hide_scrollbar),
mReserveScrollCorner(p.reserve_scroll_corner),
mMinAutoScrollRate(p.min_auto_scroll_rate),
mMaxAutoScrollRate(p.max_auto_scroll_rate),
@ -349,28 +351,33 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
*visible_width = getRect().getWidth() - 2 * mBorder->getBorderWidth();
*visible_height = getRect().getHeight() - 2 * mBorder->getBorderWidth();
S32 border_width = (mBorder->getVisible() ? 2 * mBorder->getBorderWidth() : 0);
*visible_width = getRect().getWidth() - border_width;
*visible_height = getRect().getHeight() - border_width;
*show_v_scrollbar = FALSE;
if( *visible_height < doc_height )
{
*show_v_scrollbar = TRUE;
*visible_width -= scrollbar_size;
}
*show_h_scrollbar = FALSE;
if( *visible_width < doc_width )
{
*show_h_scrollbar = TRUE;
*visible_height -= scrollbar_size;
// Must retest now that visible_height has changed
if( !*show_v_scrollbar && (*visible_height < doc_height) )
if (!mHideScrollbar)
{
if( *visible_height < doc_height )
{
*show_v_scrollbar = TRUE;
*visible_width -= scrollbar_size;
}
if( *visible_width < doc_width )
{
*show_h_scrollbar = TRUE;
*visible_height -= scrollbar_size;
// Must retest now that visible_height has changed
if( !*show_v_scrollbar && (*visible_height < doc_height) )
{
*show_v_scrollbar = TRUE;
*visible_width -= scrollbar_size;
}
}
}
}
@ -457,19 +464,6 @@ void LLScrollContainer::draw()
sDepth--;
}
}
if (sDebugRects)
{
drawDebugRect();
}
//// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
//std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
//if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
//{
// drawDebugRect();
//}
} // end draw
bool LLScrollContainer::addChild(LLView* view, S32 tab_group)
@ -598,7 +592,7 @@ LLRect LLScrollContainer::getContentWindowRect() const
BOOL show_h_scrollbar = FALSE;
BOOL show_v_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
S32 border_width = mBorder->getBorderWidth();
S32 border_width = mBorder->getVisible() ? mBorder->getBorderWidth() : 0;
scroller_view_rect.setOriginAndSize(border_width,
show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width,
visible_width,

View File

@ -68,7 +68,8 @@ public:
{
Optional<bool> is_opaque,
reserve_scroll_corner,
border_visible;
border_visible,
hide_scrollbar;
Optional<F32> min_auto_scroll_rate,
max_auto_scroll_rate;
Optional<LLUIColor> bg_color;
@ -139,6 +140,7 @@ private:
F32 mAutoScrollRate;
F32 mMinAutoScrollRate;
F32 mMaxAutoScrollRate;
bool mHideScrollbar;
};

View File

@ -204,6 +204,13 @@ BOOL LLScrollListText::isText() const
return TRUE;
}
BOOL LLScrollListText::needsToolTip() const
{
// show tooltips for truncated text
return mFont->getWidth(mText.getString()) > getWidth();
}
//virtual
BOOL LLScrollListText::getVisible() const
{

View File

@ -94,16 +94,18 @@ public:
LLScrollListCell(const LLScrollListCell::Params&);
virtual ~LLScrollListCell() {};
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible
virtual void draw(const LLColor4& color, const LLColor4& highlight_color) const {}; // truncate to given width, if possible
virtual S32 getWidth() const {return mWidth;}
virtual S32 getContentWidth() const { return 0; }
virtual S32 getHeight() const = 0;
virtual S32 getHeight() const { return 0; }
virtual const LLSD getValue() const;
virtual void setValue(const LLSD& value) { }
virtual BOOL getVisible() const { return TRUE; }
virtual void setWidth(S32 width) { mWidth = width; }
virtual void highlightText(S32 offset, S32 num_chars) {}
virtual BOOL isText() const = 0;
virtual BOOL isText() const { return FALSE; }
virtual BOOL needsToolTip() const { return FALSE; }
virtual void setColor(const LLColor4&) {}
virtual void onCommit() {};
@ -120,8 +122,6 @@ public:
LLScrollListSpacer(const LLScrollListCell::Params& p) : LLScrollListCell(p) {}
/*virtual*/ ~LLScrollListSpacer() {};
/*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const {}
/*virtual*/ S32 getHeight() const { return 0; }
/*virtual*/ BOOL isText() const { return FALSE; }
};
/*
@ -143,6 +143,7 @@ public:
/*virtual*/ void setColor(const LLColor4&);
/*virtual*/ BOOL isText() const;
/*virtual*/ BOOL needsToolTip() const;
void setText(const LLStringExplicit& text);
void setFontStyle(const U8 font_style);
@ -175,7 +176,6 @@ public:
/*virtual*/ S32 getHeight() const;
/*virtual*/ const LLSD getValue() const;
/*virtual*/ void setColor(const LLColor4&);
/*virtual*/ BOOL isText()const { return FALSE; }
/*virtual*/ void setValue(const LLSD& value);
private:
@ -202,7 +202,6 @@ public:
/*virtual*/ void setEnabled(BOOL enable);
LLCheckBoxCtrl* getCheckBox() { return mCheckBox; }
/*virtual*/ BOOL isText() const { return FALSE; }
private:
LLCheckBoxCtrl* mCheckBox;

View File

@ -218,7 +218,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
sbparams.orientation(LLScrollbar::VERTICAL);
sbparams.doc_size(getItemCount());
sbparams.doc_pos(mScrollLines);
sbparams.page_size( mPageLines ? mPageLines : getItemCount() );
sbparams.page_size( getLinesPerPage() );
sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2));
sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
sbparams.visible(false);
@ -475,10 +475,7 @@ void LLScrollListCtrl::updateLayout()
getChildView("comment_text")->setShape(mItemListRect);
// how many lines of content in a single "page"
S32 page_lines = mLineHeight? mItemListRect.getHeight() / mLineHeight : getItemCount();
//if mPageLines is NOT provided display all item
if(mPageLines)
page_lines = mPageLines;
S32 page_lines = getLinesPerPage();
BOOL scrollbar_visible = mLineHeight * getItemCount() > mItemListRect.getHeight();
if (scrollbar_visible)
@ -1386,7 +1383,7 @@ void LLScrollListCtrl::drawItems()
S32 y = mItemListRect.mTop - mLineHeight;
// allow for partial line at bottom
S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;
S32 num_page_lines = getLinesPerPage();
LLRect item_rect;
@ -1529,7 +1526,19 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
return handled;
}
BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
// *NOTE: Requires a valid row_index and column_index
LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index)
{
LLRect cell_rect;
S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;
S32 rect_bottom = getRowOffsetFromIndex(row_index);
LLScrollListColumn* columnp = getColumn(column_index);
cell_rect.setOriginAndSize(rect_left, rect_bottom,
rect_left + columnp->getWidth(), mLineHeight);
return cell_rect;
}
BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
{
S32 column_index = getColumnIndexFromOffset(x);
LLScrollListColumn* columnp = getColumn(column_index);
@ -1543,20 +1552,23 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sti
{
LLScrollListCell* hit_cell = hit_item->getColumn(column_index);
if (!hit_cell) return FALSE;
//S32 cell_required_width = hit_cell->getContentWidth();
if (hit_cell
&& hit_cell->isText())
&& hit_cell->isText()
&& hit_cell->needsToolTip())
{
S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;
S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item));
LLRect cell_rect;
cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight);
S32 row_index = getItemIndex(hit_item);
LLRect cell_rect = getCellRect(row_index, column_index);
// Convert rect local to screen coordinates
LLRect sticky_rect;
localRectToScreen(cell_rect, &sticky_rect);
LLToolTipMgr::instance().show(LLToolTipParams()
.message(hit_cell->getValue().asString())
.sticky_rect(sticky_rect));
// display tooltip exactly over original cell, in same font
LLToolTipMgr::instance().show(LLToolTip::Params()
.message(hit_cell->getValue().asString())
.font(LLFontGL::getFontSansSerifSmall())
.pos(LLCoordGL(sticky_rect.mLeft - 5, sticky_rect.mTop + 4))
.delay_time(0.2f)
.sticky_rect(sticky_rect));
}
handled = TRUE;
}
@ -1565,7 +1577,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sti
LLScrollColumnHeader* headerp = columnp->mHeader;
if (headerp && !handled)
{
handled = headerp->handleToolTip(x, y, msg, sticky_rect_screen);
handled = headerp->handleToolTip(x, y, mask);
}
return handled;
@ -1877,7 +1889,7 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y )
mLineHeight );
// allow for partial line at bottom
S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;
S32 num_page_lines = getLinesPerPage();
S32 line = 0;
item_list::iterator iter;
@ -2336,6 +2348,20 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
}
}
S32 LLScrollListCtrl::getLinesPerPage()
{
//if mPageLines is NOT provided display all item
if(mPageLines)
{
return mPageLines;
}
else
{
return mLineHeight ? mItemListRect.getHeight() / mLineHeight : getItemCount();
}
}
// Called by scrollbar
void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar )
{
@ -2442,7 +2468,7 @@ void LLScrollListCtrl::scrollToShowSelected()
}
S32 lowest = mScrollLines;
S32 page_lines = (mPageLines)? mPageLines : getItemCount();
S32 page_lines = getLinesPerPage();
S32 highest = mScrollLines + page_lines;
if (index < lowest)

View File

@ -288,7 +288,7 @@ public:
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
/*virtual*/ void setEnabled(BOOL enabled);
/*virtual*/ void setFocus( BOOL b );
/*virtual*/ void onFocusReceived();
@ -307,6 +307,9 @@ public:
LLRect getItemListRect() { return mItemListRect; }
/// Returns rect, in local coords, of a given row/column
LLRect getCellRect(S32 row_index, S32 column_index);
// Used "internally" by the scroll bar.
void onScrollChange( S32 new_pos, LLScrollbar* src );
@ -390,6 +393,7 @@ private:
void deselectItem(LLScrollListItem* itemp);
void commitIfChanged();
BOOL setSort(S32 column, BOOL ascending);
S32 getLinesPerPage();
static void showNameDetails(std::string id, bool is_group);
static void copyNameToClipboard(std::string id, bool is_group);

View File

@ -36,7 +36,6 @@
#include "llscrolllistitem.h"
#include "llrect.h"
#include "llresmgr.h" // LLFONT_SANSSERIF_SMALL
#include "llui.h"

View File

@ -34,10 +34,8 @@
#ifndef LLSCROLLLISTITEM_H
#define LLSCROLLLISTITEM_H
#include "llfontgl.h" // LLFontGL::HAlign
#include "llpointer.h" // LLPointer<>
#include "llsd.h"
#include "lluistring.h"
#include "v4color.h"
#include "llinitparam.h"
#include "llscrolllistcell.h"

View File

@ -83,7 +83,7 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
LLTextBox::Params params(p.slider_label);
params.rect.setIfNotProvided(label_rect);
params.font.setIfNotProvided(p.font);
params.text(p.label);
params.initial_value(p.label());
mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mLabelBox);
}

View File

@ -90,7 +90,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
LLTextBox::Params params;
params.name("SpinCtrl Label");
params.rect(label_rect);
params.text(p.label);
params.initial_value(p.label());
if (p.font.isProvided())
{
params.font(p.font);

View File

@ -67,5 +67,7 @@ LLStatView::~LLStatView()
static StatViewRegistry::Register<LLStatBar> r1("stat_bar");
static StatViewRegistry::Register<LLStatView> r2("stat_view");
// stat_view can be a child of panels/etc.
static LLDefaultChildRegistry::Register<LLStatView> r3("stat_view");

View File

@ -40,7 +40,7 @@
LLStyle::Params::Params()
: visible("visible", true),
drop_shadow("drop_shadow", false),
drop_shadow("drop_shadow", LLFontGL::NO_SHADOW),
color("color", LLColor4::black),
font("font", LLFontGL::getFontMonospace()),
image("image"),

View File

@ -44,12 +44,12 @@ class LLStyle : public LLRefCount
public:
struct Params : public LLInitParam::Block<Params>
{
Optional<bool> visible,
drop_shadow;
Optional<LLUIColor> color;
Optional<const LLFontGL*> font;
Optional<LLUIImage*> image;
Optional<std::string> link_href;
Optional<bool> visible;
Optional<LLFontGL::ShadowType> drop_shadow;
Optional<LLUIColor> color;
Optional<const LLFontGL*> font;
Optional<LLUIImage*> image;
Optional<std::string> link_href;
Params();
};
LLStyle(const Params& p = Params());
@ -60,6 +60,8 @@ public:
BOOL isVisible() const;
void setVisible(BOOL is_visible);
LLFontGL::ShadowType getShadowType() { return mDropShadow; }
void setFont(const LLFontGL* font);
const LLFontGL* getFont() const;
@ -94,7 +96,7 @@ public:
BOOL mItalic;
BOOL mBold;
BOOL mUnderline;
BOOL mDropShadow;
LLFontGL::ShadowType mDropShadow;
protected:
~LLStyle() { }

View File

@ -596,10 +596,10 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )
}
// virtual
BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect& sticky_rect )
BOOL LLTabContainer::handleToolTip( S32 x, S32 y, MASK mask)
{
static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect );
BOOL handled = LLPanel::handleToolTip( x, y, mask);
if (!handled && getTabCount() > 0)
{
LLTabTuple* firsttuple = getTab(0);
@ -629,7 +629,7 @@ BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect& stic
tuple->mButton->setVisible( TRUE );
S32 local_x = x - tuple->mButton->getRect().mLeft;
S32 local_y = y - tuple->mButton->getRect().mBottom;
handled = tuple->mButton->handleToolTip( local_x, local_y, msg, sticky_rect );
handled = tuple->mButton->handleToolTip( local_x, local_y, mask);
if( handled )
{
break;
@ -906,7 +906,7 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
LLTextBox::Params params;
params.name(trimmed_label);
params.rect(btn_rect);
params.text(trimmed_label);
params.initial_value(trimmed_label);
params.font(font);
textbox = LLUICtrlFactory::create<LLTextBox> (params);

View File

@ -99,7 +99,7 @@ public:
/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect );
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType type, void* cargo_data,

File diff suppressed because it is too large Load Diff

View File

@ -35,13 +35,16 @@
#define LL_LLTEXTBASE_H
#include "v4color.h"
#include "lleditmenuhandler.h"
#include "llstyle.h"
#include "llkeywords.h"
#include "lluictrl.h"
#include "llpanel.h"
#include <string>
#include <set>
#include <boost/signals2.hpp>
class LLContextMenu;
class LLTextSegment;
@ -52,64 +55,307 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
/// as LLTextEditor and LLTextBox. It implements shared functionality
/// such as Url highlighting and opening.
///
class LLTextBase
class LLTextBase
: public LLUICtrl,
protected LLEditMenuHandler
{
public:
LLTextBase(const LLUICtrl::Params &p);
virtual ~LLTextBase();
struct LineSpacingParams : public LLInitParam::Choice<LineSpacingParams>
{
Alternative<F32> multiple;
Alternative<S32> pixels;
LineSpacingParams();
};
/// specify the color to display Url hyperlinks in the text
static void setLinkColor(LLColor4 color) { mLinkColor = color; }
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<LLUIColor> cursor_color,
text_color,
text_readonly_color,
bg_readonly_color,
bg_writeable_color,
bg_focus_color;
/// enable/disable the automatic hyperlinking of Urls in the text
void setParseHTML(BOOL parsing) { mParseHTML=parsing; }
Optional<bool> bg_visible,
border_visible,
track_end,
read_only,
hide_scrollbar,
clip_to_rect,
wrap,
use_ellipses,
allow_html,
parse_highlights;
Optional<S32> v_pad,
h_pad;
// public text editing virtual methods
virtual LLWString getWText() const = 0;
virtual BOOL allowsEmbeddedItems() const { return FALSE; }
virtual BOOL getWordWrap() { return mWordWrap; }
virtual S32 getLength() const = 0;
Optional<LineSpacingParams>
line_spacing;
Optional<S32> max_text_length;
Optional<LLFontGL::ShadowType> font_shadow;
Params();
};
// LLMouseHandler interface
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
// LLView interface
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ void draw();
// LLUICtrl interface
/*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; }
/*virtual*/ void clear();
/*virtual*/ void setColor( const LLColor4& c );
/*virtual*/ void setValue(const LLSD& value );
/*virtual*/ LLTextViewModel* getViewModel() const;
// LLEditMenuHandler interface
/*virtual*/ void deselect();
// used by LLTextSegment layout code
bool getWordWrap() { return mWordWrap; }
bool getUseEllipses() { return mUseEllipses; }
bool truncate(); // returns true of truncation occurred
// TODO: move into LLTextSegment?
void createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url
// Text accessors
// TODO: add optional style parameter
virtual void setText(const LLStringExplicit &utf8str); // uses default style
virtual std::string getText() const;
// wide-char versions
void setWText(const LLWString& text);
LLWString getWText() const;
void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
S32 getLength() const { return getWText().length(); }
S32 getLineCount() const { return mLineInfoList.size(); }
class DocumentPanel : public LLPanel
{
public:
DocumentPanel(const Params&);
};
void addDocumentChild(LLView* view);
void removeDocumentChild(LLView* view);
const DocumentPanel* getDocumentPanel() const { return mDocumentPanel; }
LLRect getTextRect() { return mTextRect; }
LLRect getContentsRect();
S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
LLRect getLocalRectFromDocIndex(S32 pos) const;
void setReadOnly(bool read_only) { mReadOnly = read_only; }
bool getReadOnly() { return mReadOnly; }
// cursor manipulation
bool setCursor(S32 row, S32 column);
bool setCursorPos(S32 cursor_pos, bool keep_cursor_offset = false);
void startOfLine();
void endOfLine();
void startOfDoc();
void endOfDoc();
void changePage( S32 delta );
void changeLine( S32 delta );
const LLFontGL* getDefaultFont() const { return mDefaultFont; }
public:
// Fired when a URL link is clicked
commit_signal_t mURLClickSignal;
protected:
// helper structs
struct compare_bottom;
struct compare_top;
struct line_end_compare;
typedef std::vector<LLTextSegmentPtr> segment_vec_t;
// Abstract inner base class representing an undoable editor command.
// Concrete sub-classes can be defined for operations such as insert, remove, etc.
// Used as arguments to the execute() method below.
class TextCmd
{
public:
TextCmd( S32 pos, BOOL group_with_next, LLTextSegmentPtr segment = LLTextSegmentPtr() )
: mPos(pos),
mGroupWithNext(group_with_next)
{
if (segment.notNull())
{
mSegments.push_back(segment);
}
}
virtual ~TextCmd() {}
virtual BOOL execute(LLTextBase* editor, S32* delta) = 0;
virtual S32 undo(LLTextBase* editor) = 0;
virtual S32 redo(LLTextBase* editor) = 0;
virtual BOOL canExtend(S32 pos) const { return FALSE; }
virtual void blockExtensions() {}
virtual BOOL extendAndExecute( LLTextBase* editor, S32 pos, llwchar c, S32* delta ) { llassert(0); return 0; }
virtual BOOL hasExtCharValue( llwchar value ) const { return FALSE; }
// Defined here so they can access protected LLTextEditor editing methods
S32 insert(LLTextBase* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr, &mSegments ); }
S32 remove(LLTextBase* editor, S32 pos, S32 length) { return editor->removeStringNoUndo( pos, length ); }
S32 overwrite(LLTextBase* editor, S32 pos, llwchar wc) { return editor->overwriteCharNoUndo(pos, wc); }
S32 getPosition() const { return mPos; }
BOOL groupWithNext() const { return mGroupWithNext; }
protected:
const S32 mPos;
BOOL mGroupWithNext;
segment_vec_t mSegments;
};
struct compare_segment_end
{
bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const;
};
typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t;
// routines to manage segments
void getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const;
void getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp );
LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y );
// protected member variables
// List of offsets and segment index of the start of each line. Always has at least one node (0).
struct line_info
{
line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num);
S32 mDocIndexStart;
S32 mDocIndexEnd;
LLRect mRect;
S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap)
};
typedef std::vector<line_info> line_list_t;
// member functions
LLTextBase(const Params &p);
virtual ~LLTextBase();
void initFromParams(const Params& p);
LLStyle::Params getDefaultStyle();
virtual void onValueChange(S32 start, S32 end);
// draw methods
void drawSelectionBackground(); // draws the black box behind the selected text
void drawCursor();
void drawText();
// modify contents
S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted
S32 removeStringNoUndo(S32 pos, S32 length);
S32 overwriteCharNoUndo(S32 pos, llwchar wc);
void appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& stylep);
// manage segments
void getSegmentAndOffset( S32 startpos, segment_set_t::const_iterator* seg_iter, S32* offsetp ) const;
void getSegmentAndOffset( S32 startpos, segment_set_t::iterator* seg_iter, S32* offsetp );
LLTextSegmentPtr getSegmentAtLocalPos( S32 x, S32 y );
segment_set_t::iterator getSegIterContaining(S32 index);
segment_set_t::const_iterator getSegIterContaining(S32 index) const;
void clearSegments();
void setHoverSegment(LLTextSegmentPtr segment);
void clearSegments();
void createDefaultSegment();
virtual void updateSegments();
void insertSegment(LLTextSegmentPtr segment_to_insert);
// manage lines
S32 getLineStart( S32 line ) const;
S32 getLineNumFromDocIndex( S32 doc_index, bool include_wordwrap = true) const;
S32 getLineOffsetFromDocIndex( S32 doc_index, bool include_wordwrap = true) const;
S32 getFirstVisibleLine() const;
std::pair<S32, S32> getVisibleLines() const;
S32 getLeftOffset(S32 width);
void reflow(S32 start_index = 0);
// event handling for Urls within the text field
BOOL handleHoverOverUrl(S32 x, S32 y);
BOOL handleMouseUpOverUrl(S32 x, S32 y);
BOOL handleRightMouseDownOverUrl(LLView *view, S32 x, S32 y);
BOOL handleToolTipForUrl(LLView *view, S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen);
// cursor
void updateCursorXPos();
void setCursorAtLocalPos( S32 local_x, S32 local_y, bool round, bool keep_cursor_offset=false );
S32 getEditableIndex(S32 index, bool increasing_direction); // constraint cursor to editable segments of document
void resetCursorBlink() { mCursorBlinkTimer.reset(); }
void updateScrollFromCursor();
// pure virtuals that have to be implemented by any subclasses
virtual S32 getLineCount() const = 0;
virtual S32 getLineStart( S32 line ) const = 0;
virtual S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const = 0;
// text selection
bool hasSelection() const { return (mSelectionStart !=mSelectionEnd); }
void startSelection();
void endSelection();
// protected member variables
static LLUIColor mLinkColor;
const LLFontGL *mDefaultFont;
segment_set_t mSegments;
LLTextSegmentPtr mHoverSegment;
BOOL mParseHTML;
BOOL mWordWrap;
// misc
void updateTextRect();
void needsReflow() { mReflowNeeded = TRUE; }
void needsScroll() { mScrollNeeded = TRUE; }
void replaceUrlLabel(const std::string &url, const std::string &label);
private:
// create a popup context menu for the given Url
static LLContextMenu *createUrlContextMenu(const std::string &url);
protected:
// text segmentation and flow
segment_set_t mSegments;
line_list_t mLineInfoList;
LLRect mTextRect; // The rect in which text is drawn. Excludes borders.
LLRect mContentsRect;
// colors
LLUIColor mCursorColor;
LLUIColor mFgColor;
LLUIColor mReadOnlyFgColor;
LLUIColor mWriteableBgColor;
LLUIColor mReadOnlyBgColor;
LLUIColor mFocusBgColor;
// cursor
S32 mCursorPos; // I-beam is just after the mCursorPos-th character.
S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be
LLFrameTimer mCursorBlinkTimer; // timer that controls cursor blinking
// selection
S32 mSelectionStart;
S32 mSelectionEnd;
BOOL mIsSelecting; // Are we in the middle of a drag-select?
// configuration
S32 mHPad; // padding on left of text
S32 mVPad; // padding above text
LLFontGL::HAlign mHAlign;
F32 mLineSpacingMult; // multiple of line height used as space for a single line of text (e.g. 1.5 to get 50% padding)
S32 mLineSpacingPixels; // padding between lines
const LLFontGL* mDefaultFont; // font that is used when none specified
LLFontGL::ShadowType mFontShadow;
bool mBorderVisible;
bool mParseHTML; // make URLs interactive
bool mParseHighlights; // highlight user-defined keywords
bool mWordWrap;
bool mUseEllipses;
bool mTrackEnd; // if true, keeps scroll position at end of document during resize
bool mReadOnly;
bool mClip;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
// support widgets
LLContextMenu* mPopupMenu;
DocumentPanel* mDocumentPanel;
class LLScrollContainer* mScroller;
// transient state
bool mReflowNeeded; // need to reflow text because of change to text contents or display region
bool mScrollNeeded; // need to change scroll region because of change to cursor position
S32 mScrollIndex; // index of first character to keep visible in scroll region
LLContextMenu *mPopupMenu;
};
///
@ -118,7 +364,7 @@ private:
/// includes a start/end offset from the start of the string, a
/// style to render with, an optional tooltip, etc.
///
class LLTextSegment : public LLRefCount
class LLTextSegment : public LLRefCount, public LLMouseHandler
{
public:
LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
@ -134,17 +380,32 @@ public:
virtual void unlinkFromDocument(class LLTextBase* editor);
virtual void linkToDocument(class LLTextBase* editor);
virtual void setHasMouseHover(bool hover);
virtual const LLColor4& getColor() const;
virtual void setColor(const LLColor4 &color);
virtual const LLStyleSP getStyle() const;
virtual void setStyle(const LLStyleSP &style);
virtual void setToken( LLKeywordToken* token );
virtual LLKeywordToken* getToken() const;
virtual BOOL getToolTip( std::string& msg ) const;
virtual void setToolTip(const std::string& tooltip);
virtual void dump() const;
// LLMouseHandler interface
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
/*virtual*/ std::string getName() const;
/*virtual*/ void onMouseCaptureLost();
/*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const;
/*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
/*virtual*/ BOOL hasMouseCapture();
S32 getStart() const { return mStart; }
void setStart(S32 start) { mStart = start; }
S32 getEnd() const { return mEnd; }
@ -167,7 +428,6 @@ public:
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
/*virtual*/ S32 getMaxHeight() const;
/*virtual*/ bool canEdit() const { return true; }
/*virtual*/ void setHasMouseHover(bool hover) { mHasMouseHover = hover; }
/*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); }
/*virtual*/ void setColor(const LLColor4 &color) { mStyle->setColor(color); }
/*virtual*/ const LLStyleSP getStyle() const { return mStyle; }
@ -178,15 +438,20 @@ public:
/*virtual*/ void setToolTip(const std::string& tooltip);
/*virtual*/ void dump() const;
protected:
F32 drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, F32 x, F32 y);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
protected:
F32 drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect);
protected:
class LLTextBase& mEditor;
LLStyleSP mStyle;
S32 mMaxHeight;
LLKeywordToken* mToken;
bool mHasMouseHover;
std::string mTooltip;
LLStyleSP mStyle;
S32 mMaxHeight;
LLKeywordToken* mToken;
std::string mTooltip;
};
class LLIndexSegment : public LLTextSegment
@ -195,4 +460,23 @@ public:
LLIndexSegment(S32 pos) : LLTextSegment(pos, pos) {}
};
class LLInlineViewSegment : public LLTextSegment
{
public:
LLInlineViewSegment(LLView* widget, S32 start, S32 end);
~LLInlineViewSegment();
/*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const;
/*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
/*virtual*/ void updateLayout(const class LLTextBase& editor);
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
/*virtuaL*/ S32 getMaxHeight() const;
/*virtual*/ bool canEdit() const { return false; }
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
/*virtual*/ void linkToDocument(class LLTextBase* editor);
private:
LLView* mView;
};
#endif

View File

@ -40,47 +40,10 @@
static LLDefaultChildRegistry::Register<LLTextBox> r("text");
LLTextBox::Params::Params()
: text_color("text_color"),
length("length"),
type("type"),
border_visible("border_visible", false),
border_drop_shadow_visible("border_drop_shadow_visible", false),
bg_visible("bg_visible", false),
use_ellipses("use_ellipses"),
word_wrap("word_wrap", false),
drop_shadow_visible("drop_shadow_visible"),
disabled_color("disabled_color"),
background_color("background_color"),
v_pad("v_pad", 0),
h_pad("h_pad", 0),
line_spacing("line_spacing", 0),
text("text"),
font_shadow("font_shadow", LLFontGL::NO_SHADOW)
{}
LLTextBox::LLTextBox(const LLTextBox::Params& p)
: LLUICtrl(p),
LLTextBase(p),
mBackgroundVisible( p.bg_visible ),
mBorderVisible( p.border_visible ),
mShadowType( p.font_shadow ),
mBorderDropShadowVisible( p.border_drop_shadow_visible ),
mUseEllipses( p.use_ellipses ),
mHPad(p.h_pad),
mVPad(p.v_pad),
mVAlign( LLFontGL::TOP ),
mClickedCallback(NULL),
mTextColor(p.text_color()),
mDisabledColor(p.disabled_color()),
mBackgroundColor(p.background_color()),
mHAlign(p.font_halign),
mLineSpacing(p.line_spacing),
mDidWordWrap(FALSE)
{
mWordWrap = p.word_wrap;
setText( p.text() );
}
: LLTextBase(p),
mClickedCallback(NULL)
{}
BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
{
@ -101,6 +64,11 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
}
}
if (!handled)
{
handled = LLTextBase::handleMouseDown(x, y, mask);
}
return handled;
}
@ -125,528 +93,60 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
}
// handle clicks on Urls in the textbox first
if (! handleMouseUpOverUrl(x, y))
handled = LLTextBase::handleMouseUp(x, y, mask);
// DO THIS AT THE VERY END to allow the button to be destroyed
// as a result of being clicked. If mouseup in the widget,
// it's been clicked
if (mClickedCallback && !handled)
{
// DO THIS AT THE VERY END to allow the button to be destroyed
// as a result of being clicked. If mouseup in the widget,
// it's been clicked
if (mClickedCallback && ! handled)
{
mClickedCallback();
}
mClickedCallback();
}
}
return handled;
}
BOOL LLTextBox::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
// pop up a context menu for any Url under the cursor
return handleRightMouseDownOverUrl(this, x, y);
}
BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask)
{
// Check to see if we're over an HTML-style link
if (handleHoverOverUrl(x, y))
{
lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
getWindow()->setCursor(UI_CURSOR_HAND);
return TRUE;
}
return LLView::handleHover(x,y,mask);
}
BOOL LLTextBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
{
if (handleToolTipForUrl(this, x, y, msg, sticky_rect_screen))
{
return TRUE;
}
return LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen);
}
void LLTextBox::setText(const LLStringExplicit& text)
{
if(mWordWrap && !mDidWordWrap)
{
setWrappedText(text);
}
else
{
mText.assign(text);
updateDisplayTextAndSegments();
}
}
void LLTextBox::setLineLengths()
{
mLineLengthList.clear();
// does string argument insertion
mText.assign(text);
std::string::size_type cur = 0;
std::string::size_type len = mDisplayText.size();
while (cur < len)
{
std::string::size_type end = mDisplayText.find('\n', cur);
std::string::size_type runLen;
if (end == std::string::npos)
{
runLen = len - cur;
cur = len;
}
else
{
runLen = end - cur;
cur = end + 1; // skip the new line character
}
mLineLengthList.push_back( (S32)runLen );
}
}
LLWString LLTextBox::wrapText(const LLWString &wtext, S32 &hoffset, S32 &line_num, F32 max_width)
{
LLWString final_wtext;
LLWString::size_type cur = 0;
LLWString::size_type len = wtext.size();
while (cur < len)
{
LLWString::size_type end = wtext.find('\n', cur);
if (end == LLWString::npos)
{
end = len;
}
bool charsRemaining = true;
LLWString::size_type runLen = end - cur;
if (runLen > 0)
{
// work out how many chars can fit onto the current line
LLWString run(wtext, cur, runLen);
LLWString::size_type useLen =
mDefaultFont->maxDrawableChars(run.c_str(), max_width-hoffset, runLen, TRUE);
charsRemaining = (cur + useLen < len);
// try to break lines on word boundaries
if (useLen < run.size())
{
LLWString::size_type prev_use_len = useLen;
while (useLen > 0 && ! isspace(run[useLen-1]) && ! ispunct(run[useLen-1]))
{
--useLen;
}
if (useLen == 0)
{
useLen = prev_use_len;
}
}
// add the chars that could fit onto one line to our result
final_wtext.append(wtext, cur, useLen);
cur += useLen;
hoffset += mDefaultFont->getWidth(run.substr(0, useLen).c_str());
// abort if not enough room to add any more characters
if (useLen == 0)
{
break;
}
}
if (charsRemaining)
{
if (wtext[cur] == '\n')
{
cur += 1;
}
final_wtext += '\n';
hoffset = 0;
line_num += 1;
}
}
return final_wtext;
}
void LLTextBox::setWrappedText(const LLStringExplicit& in_text, F32 max_width)
{
mDidWordWrap = TRUE;
setText(wstring_to_utf8str(getWrappedText(in_text, max_width)));
}
LLWString LLTextBox::getWrappedText(const LLStringExplicit& in_text, F32 max_width)
{
//
// we don't want to wrap Urls otherwise we won't be able to detect their
// presence for hyperlinking. So we look for all Urls, and then word wrap
// the text before and after, but never break a Url in the middle. We
// also need to consider that the Url will be displayed as a label (not
// necessary the actual Url string).
//
if (max_width < 0.0f)
{
max_width = (F32)getRect().getWidth();
}
LLWString wtext = utf8str_to_wstring(in_text);
LLWString final_wtext;
S32 line_num = 1;
S32 hoffset = 0;
// find the next Url in the text string
LLUrlMatch match;
while ( LLUrlRegistry::instance().findUrl(wtext, match))
{
S32 start = match.getStart();
S32 end = match.getEnd() + 1;
// perform word wrap on the text before the Url
final_wtext += wrapText(wtext.substr(0, start), hoffset, line_num, max_width);
// add the Url (but compute width based on its label)
S32 label_width = mDefaultFont->getWidth(match.getLabel());
if (hoffset > 0 && hoffset + label_width > max_width)
{
final_wtext += '\n';
line_num++;
hoffset = 0;
}
final_wtext += wtext.substr(start, end-start);
hoffset += label_width;
if (hoffset > max_width)
{
final_wtext += '\n';
line_num++;
hoffset = 0;
// eat any leading whitespace on the next line
while (isspace(wtext[end]) && end < (S32)wtext.size())
{
end++;
}
}
// move on to the rest of the text after the Url
wtext = wtext.substr(end, wtext.size() - end + 1);
}
final_wtext += wrapText(wtext, hoffset, line_num, max_width);
return final_wtext;
LLTextBase::setText(mText.getString());
}
S32 LLTextBox::getTextPixelWidth()
{
S32 max_line_width = 0;
if( mLineLengthList.size() > 0 )
{
S32 cur_pos = 0;
for (std::vector<S32>::iterator iter = mLineLengthList.begin();
iter != mLineLengthList.end(); ++iter)
{
S32 line_length = *iter;
S32 line_width = mDefaultFont->getWidth( mDisplayText.c_str(), cur_pos, line_length );
if( line_width > max_line_width )
{
max_line_width = line_width;
}
cur_pos += line_length+1;
}
}
else
{
max_line_width = mDefaultFont->getWidth(mDisplayText.c_str());
}
return max_line_width;
return getContentsRect().getWidth();
}
S32 LLTextBox::getTextPixelHeight()
{
S32 num_lines = mLineLengthList.size();
if( num_lines < 1 )
{
num_lines = 1;
}
return (S32)(num_lines * mDefaultFont->getLineHeight());
}
void LLTextBox::setValue(const LLSD& value )
{
mDidWordWrap = FALSE;
setText(value.asString());
return getContentsRect().getHeight();
}
BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )
{
mText.setArg(key, text);
updateDisplayTextAndSegments();
LLTextBase::setText(mText.getString());
return TRUE;
}
void LLTextBox::draw()
{
F32 alpha = getDrawContext().mAlpha;
if (mBorderVisible)
{
gl_rect_2d_offset_local(getLocalRect(), 2, FALSE);
}
if( mBorderDropShadowVisible )
{
static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow");
static LLUICachedControl<S32> drop_shadow_tooltip ("DropShadowTooltip", 0);
gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
color_drop_shadow % alpha, drop_shadow_tooltip);
}
if (mBackgroundVisible)
{
LLRect r( 0, getRect().getHeight(), getRect().getWidth(), 0 );
gl_rect_2d( r, mBackgroundColor.get() % alpha );
}
S32 text_x = 0;
switch( mHAlign )
{
case LLFontGL::LEFT:
text_x = mHPad;
break;
case LLFontGL::HCENTER:
text_x = getRect().getWidth() / 2;
break;
case LLFontGL::RIGHT:
text_x = getRect().getWidth() - mHPad;
break;
}
S32 text_y = getRect().getHeight() - mVPad;
if ( getEnabled() )
{
drawText( text_x, text_y, mDisplayText, mTextColor.get() );
}
else
{
drawText( text_x, text_y, mDisplayText, mDisabledColor.get() );
}
if (sDebugRects)
{
drawDebugRect();
}
//// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
//std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
//if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
//{
// drawDebugRect();
//}
}
void LLTextBox::reshape(S32 width, S32 height, BOOL called_from_parent)
{
// reparse line lengths (don't need to recalculate the display text)
setLineLengths();
LLView::reshape(width, height, called_from_parent);
}
void LLTextBox::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& color )
{
F32 alpha = getDrawContext().mAlpha;
if (mSegments.size() > 1)
{
// we have Urls (or other multi-styled segments)
drawTextSegments(x, y, text);
}
else if( mLineLengthList.empty() )
{
// simple case of 1 line of text in one style
mDefaultFont->render(text, 0, (F32)x, (F32)y, color % alpha,
mHAlign, mVAlign,
0,
mShadowType,
S32_MAX, getRect().getWidth(), NULL, mUseEllipses);
}
else
{
// simple case of multiple lines of text, all in the same style
S32 cur_pos = 0;
for (std::vector<S32>::iterator iter = mLineLengthList.begin();
iter != mLineLengthList.end(); ++iter)
{
S32 line_length = *iter;
mDefaultFont->render(text, cur_pos, (F32)x, (F32)y, color % alpha,
mHAlign, mVAlign,
0,
mShadowType,
line_length, getRect().getWidth(), NULL, mUseEllipses );
cur_pos += line_length + 1;
S32 line_height = llfloor(mDefaultFont->getLineHeight()) + mLineSpacing;
y -= line_height;
if(y < line_height)
break;
}
}
}
void LLTextBox::reshapeToFitText()
{
// wrap remaining lines that did not fit on call to setWrappedText()
setLineLengths();
reflow();
S32 width = getTextPixelWidth();
S32 height = getTextPixelHeight();
reshape( width + 2 * mHPad, height + 2 * mVPad );
reshape( width + 2 * mHPad, height + 2 * mVPad, FALSE );
}
S32 LLTextBox::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const
{
// Returns the character offset for the character under the local (x, y) coordinate.
// When round is true, if the position is on the right half of a character, the cursor
// will be put to its right. If round is false, the cursor will always be put to the
// character's left.
LLRect rect = getLocalRect();
rect.mLeft += mHPad;
rect.mRight -= mHPad;
rect.mTop += mVPad;
rect.mBottom -= mVPad;
// Figure out which line we're nearest to.
S32 total_lines = getLineCount();
S32 line_height = llround( mDefaultFont->getLineHeight() ) + mLineSpacing;
S32 line = (rect.mTop - 1 - local_y) / line_height;
if (line >= total_lines)
{
return getLength(); // past the end
}
line = llclamp( line, 0, total_lines );
S32 line_start = getLineStart(line);
S32 next_start = getLineStart(line+1);
S32 line_end = (next_start != line_start) ? next_start - 1 : getLength();
if (line_start == -1)
{
return 0;
}
S32 line_len = line_end - line_start;
S32 pos = mDefaultFont->charFromPixelOffset(mDisplayText.c_str(), line_start,
(F32)(local_x - rect.mLeft),
(F32)rect.getWidth(),
line_len, round);
return line_start + pos;
}
S32 LLTextBox::getLineStart( S32 line ) const
{
line = llclamp(line, 0, getLineCount()-1);
S32 result = 0;
for (int i = 0; i < line; i++)
{
result += mLineLengthList[i] + 1 /* add newline */;
}
return result;
}
void LLTextBox::updateDisplayTextAndSegments()
{
// remove any previous segment list
clearSegments();
// if URL parsing is turned off, then not much to bo
if (! mParseHTML)
{
mDisplayText = mText.getWString();
setLineLengths();
return;
}
// create unique text segments for Urls
mDisplayText.clear();
S32 end = 0;
LLUrlMatch match;
LLWString text = mText.getWString();
// find the next Url in the text string
while ( LLUrlRegistry::instance().findUrl(text, match,
boost::bind(&LLTextBox::onUrlLabelUpdated, this, _1, _2)) )
{
// work out the char offset for the start/end of the url
S32 url_start = match.getStart();
S32 url_end = match.getEnd();
// and the char offset for the label in the display text
S32 seg_start = mDisplayText.size();
S32 start = seg_start + url_start;
S32 end = start + match.getLabel().size();
// create a segment for the text before the Url
mSegments.insert(new LLNormalTextSegment(new LLStyle(), seg_start, start, *this));
mDisplayText += text.substr(0, url_start);
// create a segment for the Url text
LLStyleSP html(new LLStyle);
html->setVisible(true);
html->setColor(mLinkColor);
html->mUnderline = TRUE;
html->setLinkHREF(match.getUrl());
LLNormalTextSegment *html_seg = new LLNormalTextSegment(html, start, end, *this);
html_seg->setToolTip(match.getTooltip());
mSegments.insert(html_seg);
mDisplayText += utf8str_to_wstring(match.getLabel());
// move on to the rest of the text after the Url
text = text.substr(url_end+1, text.size() - url_end);
}
// output a segment for the remaining text
if (text.size() > 0)
{
mSegments.insert(new LLNormalTextSegment(new LLStyle(), end, end + text.size(), *this));
mDisplayText += text;
}
// strip whitespace from the end of the text
while (mDisplayText.size() > 0 && isspace(mDisplayText[mDisplayText.size()-1]))
{
mDisplayText = mDisplayText.substr(0, mDisplayText.size() - 1);
segment_set_t::iterator it = getSegIterContaining(mDisplayText.size());
if (it != mSegments.end())
{
LLTextSegmentPtr seg = *it;
seg->setEnd(seg->getEnd()-1);
}
}
// we may have changed the line lengths, so recalculate them
setLineLengths();
}
void LLTextBox::onUrlLabelUpdated(const std::string &url, const std::string &label)
{
if (mDidWordWrap)
{
// re-word wrap as the url label lengths may have changed
setWrappedText(mText.getString());
}
else
{
// or just update the display text with the latest Url labels
updateDisplayTextAndSegments();
}
needsReflow();
}
bool LLTextBox::isClickable() const
@ -676,89 +176,3 @@ bool LLTextBox::isClickable() const
return false;
}
void LLTextBox::drawTextSegments(S32 init_x, S32 init_y, const LLWString &text)
{
F32 alpha = getDrawContext().mAlpha;
const S32 text_len = text.length();
if (text_len <= 0)
{
return;
}
S32 cur_line = 0;
S32 num_lines = getLineCount();
S32 line_start = getLineStart(cur_line);
S32 line_height = llround( mDefaultFont->getLineHeight() ) + mLineSpacing;
F32 text_y = (F32) init_y;
segment_set_t::iterator cur_seg = mSegments.begin();
// render a line of text at a time
const LLRect textRect = getLocalRect();
while((textRect.mBottom <= text_y) && (cur_line < num_lines))
{
S32 next_start = -1;
S32 line_end = text_len;
if ((cur_line + 1) < num_lines)
{
next_start = getLineStart(cur_line + 1);
line_end = next_start;
}
if ( text[line_end-1] == '\n' )
{
--line_end;
}
// render all segments on this line
F32 text_x = init_x;
S32 seg_start = line_start;
while (seg_start < line_end && cur_seg != mSegments.end())
{
// move to the next segment (or continue the previous one)
LLTextSegment *cur_segment = *cur_seg;
while (cur_segment->getEnd() <= seg_start)
{
if (++cur_seg == mSegments.end())
{
return;
}
cur_segment = *cur_seg;
}
// Draw a segment within the line
S32 clipped_end = llmin( line_end, cur_segment->getEnd() );
S32 clipped_len = clipped_end - seg_start;
if( clipped_len > 0 )
{
LLStyleSP style = cur_segment->getStyle();
if (style && style->isVisible())
{
// work out the color for the segment
LLColor4 color ;
if (getEnabled())
{
color = style->isLink() ? mLinkColor.get() : mTextColor.get();
}
else
{
color = mDisabledColor.get();
}
color = color % alpha;
// render a single line worth for this segment
mDefaultFont->render(text, seg_start, text_x, text_y, color,
mHAlign, mVAlign, 0, mShadowType, clipped_len,
textRect.getWidth(), &text_x, mUseEllipses);
}
seg_start += clipped_len;
}
}
// move down one line
text_y -= (F32)line_height;
line_start = next_start;
cur_line++;
}
}

View File

@ -33,47 +33,21 @@
#ifndef LL_LLTEXTBOX_H
#define LL_LLTEXTBOX_H
#include "lluictrl.h"
#include "v4color.h"
#include "llstring.h"
#include "lluistring.h"
#include "lltextbase.h"
class LLTextBox :
public LLTextBase,
public LLUICtrl
public LLTextBase
{
public:
// *TODO: Add callback to Params
typedef boost::function<void (void)> callback_t;
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<std::string> text;
Optional<bool> border_visible,
border_drop_shadow_visible,
bg_visible,
use_ellipses,
word_wrap;
Optional<LLFontGL::ShadowType> font_shadow;
Ignored drop_shadow_visible,
type,
length;
Optional<LLUIColor> text_color,
disabled_color,
background_color;
Optional<S32> v_pad,
h_pad,
line_spacing;
Params();
};
struct Params : public LLInitParam::Block<Params, LLTextBase::Params>
{};
protected:
LLTextBox(const Params&);
@ -82,84 +56,33 @@ protected:
public:
virtual ~LLTextBox() {}
virtual void draw();
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen);
void setColor( const LLColor4& c ) { mTextColor = c; }
void setDisabledColor( const LLColor4& c) { mDisabledColor = c; }
void setBackgroundColor( const LLColor4& c) { mBackgroundColor = c; }
void setText( const LLStringExplicit& text );
void setWrappedText(const LLStringExplicit& text, F32 max_width = -1.f); // -1 means use existing control width
void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; }
/*virtual*/ void setText( const LLStringExplicit& text );
void setBackgroundVisible(BOOL visible) { mBackgroundVisible = visible; }
void setBorderVisible(BOOL visible) { mBorderVisible = visible; }
void setBorderDropshadowVisible(BOOL visible){ mBorderDropShadowVisible = visible; }
void setHPad(S32 pixels) { mHPad = pixels; }
void setVPad(S32 pixels) { mVPad = pixels; }
void setRightAlign() { mHAlign = LLFontGL::RIGHT; }
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ){ mClickedCallback = boost::bind(cb, userdata); } // mouse down and up within button
const LLFontGL* getFont() const { return mDefaultFont; }
void setFont(const LLFontGL* font) { mDefaultFont = font; }
//const LLFontGL* getFont() const { return mDefaultFont; }
//void setFont(const LLFontGL* font) { mDefaultFont = font; }
void reshapeToFitText();
const std::string& getText() const { return mText.getString(); }
LLWString getWText() const { return mDisplayText; }
//const std::string& getText() const { return mText.getString(); }
S32 getTextPixelWidth();
S32 getTextPixelHeight();
S32 getLength() const { return mDisplayText.length(); }
virtual void setValue(const LLSD& value );
virtual LLSD getValue() const { return LLSD(getText()); }
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
protected:
S32 getLineCount() const { return mLineLengthList.size(); }
S32 getLineStart( S32 line ) const;
S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
LLWString getWrappedText(const LLStringExplicit& in_text, F32 max_width = -1.f);
void setLineLengths();
void updateDisplayTextAndSegments();
virtual void drawText(S32 x, S32 y, const LLWString &text, const LLColor4& color );
void onUrlLabelUpdated(const std::string &url, const std::string &label);
bool isClickable() const;
LLWString wrapText(const LLWString &wtext, S32 &hoffset, S32 &line_num, F32 max_width);
void drawTextSegments(S32 x, S32 y, const LLWString &text);
LLUIString mText;
LLWString mDisplayText;
LLUIColor mTextColor;
LLUIColor mDisabledColor;
LLUIColor mBackgroundColor;
LLUIColor mBorderColor;
BOOL mBackgroundVisible;
BOOL mBorderVisible;
BOOL mDidWordWrap;
LLFontGL::ShadowType mShadowType;
BOOL mBorderDropShadowVisible;
BOOL mUseEllipses;
S32 mLineSpacing;
S32 mHPad;
S32 mVPad;
LLFontGL::HAlign mHAlign;
LLFontGL::VAlign mVAlign;
std::vector<S32> mLineLengthList;
callback_t mClickedCallback;
LLUIString mText;
callback_t mClickedCallback;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,6 @@
#include "llrect.h"
#include "llkeywords.h"
#include "lluictrl.h"
#include "llframetimer.h"
#include "lldarray.h"
#include "llstyle.h"
@ -52,66 +51,27 @@
class LLFontGL;
class LLScrollbar;
class LLKeywordToken;
class LLTextCmd;
class TextCmd;
class LLUICtrlFactory;
class LLScrollContainer;
class LLInlineViewSegment : public LLTextSegment
{
public:
LLInlineViewSegment(LLView* widget, S32 start, S32 end);
~LLInlineViewSegment();
/*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const;
/*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
/*virtual*/ void updateLayout(const class LLTextBase& editor);
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
/*virtuaL*/ S32 getMaxHeight() const;
/*virtual*/ bool canEdit() const { return false; }
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
/*virtual*/ void linkToDocument(class LLTextBase* editor);
private:
LLView* mView;
};
class LLTextEditor :
public LLTextBase,
public LLUICtrl,
private LLEditMenuHandler,
protected LLPreeditor
{
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
struct Params : public LLInitParam::Block<Params, LLTextBase::Params>
{
Optional<std::string> default_text;
Optional<S32> max_text_length;
Optional<bool> read_only,
embedded_items,
word_wrap,
Optional<bool> embedded_items,
ignore_tab,
hide_border,
track_bottom,
handle_edit_keys_directly,
show_line_numbers,
commit_on_focus_lost;
//colors
Optional<LLUIColor> cursor_color,
default_color,
text_color,
text_readonly_color,
bg_readonly_color,
bg_writeable_color,
bg_focus_color,
link_color;
Optional<LLViewBorder::Params> border;
Ignored type,
length,
is_unicode,
hide_scrollbar;
Optional<LLUIColor> default_color;
Params();
};
@ -128,15 +88,6 @@ public:
static const llwchar LAST_EMBEDDED_CHAR = 0x10ffff;
static const S32 MAX_EMBEDDED_ITEMS = LAST_EMBEDDED_CHAR - FIRST_EMBEDDED_CHAR + 1;
struct compare_segment_end
{
bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const
{
return a->getEnd() < b->getEnd();
}
};
virtual ~LLTextEditor();
typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
@ -155,14 +106,9 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask );
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept, std::string& tooltip_msg);
virtual void onMouseCaptureLost();
// view overrides
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual void draw();
virtual void onFocusReceived();
virtual void onFocusLost();
@ -170,11 +116,8 @@ public:
virtual void setEnabled(BOOL enabled);
// uictrl overrides
virtual void clear();
virtual void setFocus( BOOL b );
virtual BOOL acceptsTextInput() const;
virtual BOOL isDirty() const;
virtual void setValue(const LLSD& value);
// LLEditMenuHandler interface
virtual void undo();
@ -201,12 +144,9 @@ public:
virtual void deselect();
virtual BOOL canDeselect() const;
virtual void onValueChange(S32 start, S32 end);
void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);
BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE);
void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive);
BOOL hasSelection() const { return (mSelectionStart !=mSelectionEnd); }
void replaceUrlLabel(const std::string &url, const std::string &label);
// Undo/redo stack
@ -216,9 +156,6 @@ public:
virtual void makePristine();
BOOL isPristine() const;
BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
S32 getLength() const { return getWText().length(); }
void setReadOnly(bool read_only) { mReadOnly = read_only; }
bool getReadOnly() { return mReadOnly; }
//
// Text manipulation
@ -226,25 +163,10 @@ public:
// inserts text at cursor
void insertText(const std::string &text);
// appends text at end
void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline,
const LLStyle::Params& style = LLStyle::Params());
void appendColoredText(const std::string &wtext, bool allow_undo,
bool prepend_newline,
const LLColor4 &color,
const std::string& font_name = LLStringUtil::null);
// if styled text starts a line, you need to prepend a newline.
void appendStyledText(const std::string &new_text, bool allow_undo,
bool prepend_newline,
const LLStyle::Params& style);
void appendHighlightedText(const std::string &new_text, bool allow_undo,
bool prepend_newline, S32 highlight_part,
const LLStyle::Params& style);
void appendWidget(LLView* widget, const std::string &widget_text, bool allow_undo, bool prepend_newline);
// Non-undoable
void setText(const LLStringExplicit &utf8str);
void setWText(const LLWString &wtext);
// Removes text from the end of document
@ -253,14 +175,9 @@ public:
BOOL tryToRevertToPristineState();
bool setCursor(S32 row, S32 column);
bool setCursorPos(S32 offset, bool keep_cursor_offset = false);
void setCursorAndScrollToEnd();
void getLineAndColumnForPosition( S32 position, S32* line, S32* col, BOOL include_wordwrap );
void getCurrentLineAndColumn( S32* line, S32* col, BOOL include_wordwrap );
S32 getLineForPosition(S32 position);
S32 getCurrentLine();
void loadKeywords(const std::string& filename,
const std::vector<std::string>& funcs,
@ -277,55 +194,17 @@ public:
virtual BOOL importBuffer(const char* buffer, S32 length );
virtual BOOL exportBuffer(std::string& buffer );
const class DocumentPanel* getDocumentPanel() const { return mDocumentPanel; }
const LLUUID& getSourceID() const { return mSourceID; }
// Callbacks
std::string getText() const;
// Callback for when a Url has been resolved by the server
void onUrlLabelUpdated(const std::string &url, const std::string &label);
// Getters
LLWString getWText() const;
llwchar getWChar(S32 pos) const { return getWText()[pos]; }
LLWString getWSubString(S32 pos, S32 len) const { return getWText().substr(pos, len); }
typedef std::vector<LLTextSegmentPtr> segment_vec_t;
const LLTextSegmentPtr getPreviousSegment() const;
void getSelectedSegments(segment_vec_t& segments) const;
void getSegmentsInRange(segment_vec_t& segments, S32 start, S32 end, bool include_partial) const;
LLRect getLocalRectFromDocIndex(S32 index) const;
void addDocumentChild(LLView* view);
void removeDocumentChild(LLView* view);
protected:
// Change cursor
void startOfLine();
void endOfLine();
void startOfDoc();
void endOfDoc();
void drawPreeditMarker();
void needsReflow() { mReflowNeeded = TRUE; }
void needsScroll() { mScrollNeeded = TRUE; }
void updateCursorXPos();
void updateScrollFromCursor();
void updateTextRect();
const LLRect& getTextRect() const { return mTextRect; }
void assignEmbedded(const std::string &s);
BOOL truncate(); // Returns true if truncation occurs
void removeCharOrTab();
void setCursorAtLocalPos(S32 x, S32 y, bool round, bool keep_cursor_offset = false);
/*virtual*/ S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const;
void indentSelectedLines( S32 spaces );
S32 indentLine( S32 pos, S32 spaces );
@ -340,68 +219,21 @@ protected:
BOOL handleEditKey(const KEY key, const MASK mask);
BOOL selectionContainsLineBreaks();
void startSelection();
void endSelection();
void deleteSelection(BOOL transient_operation);
S32 prevWordPos(S32 cursorPos) const;
S32 nextWordPos(S32 cursorPos) const;
S32 getLineCount() const { return mLineInfoList.size(); }
S32 getLineStart( S32 line ) const;
S32 getLineHeight( S32 line ) const;
void getLineAndOffset(S32 pos, S32* linep, S32* offsetp, bool include_wordwrap = true) const;
S32 getPos(S32 line, S32 offset);
void changePage(S32 delta);
void changeLine(S32 delta);
void autoIndent();
void findEmbeddedItemSegments(S32 start, S32 end);
void insertSegment(LLTextSegmentPtr segment_to_insert);
void getSegmentsInRange(segment_vec_t& segments, S32 start, S32 end, bool include_partial) const;
virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; }
// Abstract inner base class representing an undoable editor command.
// Concrete sub-classes can be defined for operations such as insert, remove, etc.
// Used as arguments to the execute() method below.
class LLTextCmd
{
public:
LLTextCmd( S32 pos, BOOL group_with_next, LLTextSegmentPtr segment = LLTextSegmentPtr() )
: mPos(pos),
mGroupWithNext(group_with_next)
{
if (segment.notNull())
{
mSegments.push_back(segment);
}
}
virtual ~LLTextCmd() {}
virtual BOOL execute(LLTextEditor* editor, S32* delta) = 0;
virtual S32 undo(LLTextEditor* editor) = 0;
virtual S32 redo(LLTextEditor* editor) = 0;
virtual BOOL canExtend(S32 pos) const { return FALSE; }
virtual void blockExtensions() {}
virtual BOOL extendAndExecute( LLTextEditor* editor, S32 pos, llwchar c, S32* delta ) { llassert(0); return 0; }
virtual BOOL hasExtCharValue( llwchar value ) const { return FALSE; }
// Defined here so they can access protected LLTextEditor editing methods
S32 insert(LLTextEditor* editor, S32 pos, const LLWString &wstr) { return editor->insertStringNoUndo( pos, wstr, &mSegments ); }
S32 remove(LLTextEditor* editor, S32 pos, S32 length) { return editor->removeStringNoUndo( pos, length ); }
S32 overwrite(LLTextEditor* editor, S32 pos, llwchar wc) { return editor->overwriteCharNoUndo(pos, wc); }
S32 getPosition() const { return mPos; }
BOOL groupWithNext() const { return mGroupWithNext; }
protected:
const S32 mPos;
BOOL mGroupWithNext;
segment_vec_t mSegments;
};
// Here's the method that takes and applies text commands.
S32 execute(LLTextCmd* cmd);
S32 execute(TextCmd* cmd);
// Undoable operations
void addChar(llwchar c); // at mCursorPos
@ -411,15 +243,7 @@ protected:
S32 removeChar(S32 pos);
S32 insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment);
S32 remove(S32 pos, S32 length, bool group_with_next_op);
S32 append(const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment);
// Direct operations
S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted
S32 removeStringNoUndo(S32 pos, S32 length);
S32 overwriteCharNoUndo(S32 pos, llwchar wc);
void resetKeystrokeTimer() { mKeystrokeTimer.reset(); }
void updateAllowingLanguageInput();
BOOL hasPreeditString() const;
@ -432,6 +256,7 @@ protected:
virtual void getSelectionRange(S32 *position, S32 *length) const;
virtual BOOL getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const;
virtual S32 getPreeditFontSize() const;
virtual LLWString getPreeditString() const { return getWText(); }
//
// Protected data
//
@ -439,74 +264,31 @@ protected:
// as possible behind protected accessor methods.
//
// I-beam is just after the mCursorPos-th character.
S32 mCursorPos;
// Use these to determine if a click on an embedded item is a drag or not.
S32 mMouseDownX;
S32 mMouseDownY;
// Are we in the middle of a drag-select? To figure out if there is a current
// selection, call hasSelection().
BOOL mIsSelecting;
S32 mSelectionStart;
S32 mSelectionEnd;
S32 mLastSelectionX;
S32 mLastSelectionY;
BOOL mParseHighlights;
// Scrollbar data
class DocumentPanel* mDocumentPanel;
LLScrollContainer* mScroller;
void *mOnScrollEndData;
LLWString mPreeditWString;
LLWString mPreeditOverwrittenWString;
std::vector<S32> mPreeditPositions;
std::vector<BOOL> mPreeditStandouts;
S32 mScrollIndex; // index into document that controls default scroll position
protected:
LLUIColor mCursorColor;
LLUIColor mFgColor;
LLUIColor mDefaultColor;
LLUIColor mReadOnlyFgColor;
LLUIColor mWriteableBgColor;
LLUIColor mReadOnlyBgColor;
LLUIColor mFocusBgColor;
LLUIColor mLinkColor;
LLUIColor mDefaultColor;
BOOL mReadOnly;
BOOL mShowLineNumbers;
BOOL mShowLineNumbers;
void updateSegments();
void updateLinkSegments();
/*virtual*/ void updateSegments();
void updateLinkSegments();
private:
//
// Methods
//
void pasteHelper(bool is_primary);
virtual LLTextViewModel* getViewModel() const;
void reflow(S32 startpos = 0);
void createDefaultSegment();
LLStyleSP getDefaultStyle();
S32 getEditableIndex(S32 index, bool increasing_direction);
void drawBackground();
void drawSelectionBackground();
void drawCursor();
void drawText();
void drawLineNumbers();
S32 getFirstVisibleLine() const;
void onKeyStroke();
//
@ -514,56 +296,25 @@ private:
//
LLKeywords mKeywords;
// Concrete LLTextCmd sub-classes used by the LLTextEditor base class
class LLTextCmdInsert;
class LLTextCmdAddChar;
class LLTextCmdOverwriteChar;
class LLTextCmdRemove;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
// Concrete TextCmd sub-classes used by the LLTextEditor base class
class TextCmdInsert;
class TextCmdAddChar;
class TextCmdOverwriteChar;
class TextCmdRemove;
class LLViewBorder* mBorder;
BOOL mBaseDocIsPristine;
LLTextCmd* mPristineCmd;
TextCmd* mPristineCmd;
LLTextCmd* mLastCmd;
TextCmd* mLastCmd;
typedef std::deque<LLTextCmd*> undo_stack_t;
typedef std::deque<TextCmd*> undo_stack_t;
undo_stack_t mUndoStack;
S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be
LLRect mTextRect; // The rect in which text is drawn. Excludes borders.
// List of offsets and segment index of the start of each line. Always has at least one node (0).
struct line_info
{
line_info(S32 index_start, S32 index_end, S32 top, S32 bottom, S32 line_num)
: mDocIndexStart(index_start),
mDocIndexEnd(index_end),
mTop(top),
mBottom(bottom),
mLineNum(line_num)
{}
S32 mDocIndexStart;
S32 mDocIndexEnd;
S32 mTop;
S32 mBottom;
S32 mLineNum; // actual line count (ignoring soft newlines due to word wrap)
};
struct compare_bottom;
struct compare_top;
struct line_end_compare;
typedef std::vector<line_info> line_list_t;
line_list_t mLineInfoList;
BOOL mReflowNeeded;
BOOL mScrollNeeded;
LLFrameTimer mKeystrokeTimer;
BOOL mTabsToNextField; // if true, tab moves focus to next field, else inserts spaces
BOOL mCommitOnFocusLost;
BOOL mTakesFocus;
BOOL mTrackBottom; // if true, keeps scroll position at bottom during resize
BOOL mAllowEmbeddedItems;

View File

@ -103,7 +103,7 @@ S32 LLTextParser::findPattern(const std::string &text, LLSD highlight)
return found;
}
LLSD LLTextParser::parsePartialLineHighlights(const std::string &text, const LLColor4 &color, S32 part, S32 index)
LLSD LLTextParser::parsePartialLineHighlights(const std::string &text, const LLColor4 &color, EHighlightPosition part, S32 index)
{
//evil recursive string atomizer.
LLSD ret_llsd, start_llsd, middle_llsd, end_llsd;
@ -122,7 +122,7 @@ LLSD LLTextParser::parsePartialLineHighlights(const std::string &text, const LLC
{
S32 end = std::string(mHighlights[i]["pattern"]).length();
S32 len = text.length();
S32 newpart;
EHighlightPosition newpart;
if (start==0)
{
start_llsd[0]["text"] =text.substr(0,end);

View File

@ -34,8 +34,6 @@
#ifndef LL_LLTEXTPARSER_H
#define LL_LLTEXTPARSER_H
#include "lltextparser.h"
#include "llsd.h"
class LLUUID;
@ -45,17 +43,17 @@ class LLColor4;
class LLTextParser
{
public:
enum ConditionType { CONTAINS, MATCHES, STARTS_WITH, ENDS_WITH };
enum HighlightType { PART, ALL };
enum HighlightPosition { WHOLE, START, MIDDLE, END };
enum DialogAction { ACTION_NONE, ACTION_CLOSE, ACTION_ADD, ACTION_COPY, ACTION_UPDATE };
typedef enum e_condition_type { CONTAINS, MATCHES, STARTS_WITH, ENDS_WITH } EConditionType;
typedef enum e_highlight_type { PART, ALL } EHighlightType;
typedef enum e_highlight_position { WHOLE, START, MIDDLE, END } EHighlightPosition;
typedef enum e_dialog_action { ACTION_NONE, ACTION_CLOSE, ACTION_ADD, ACTION_COPY, ACTION_UPDATE } EDialogAction;
static LLTextParser* getInstance();
LLTextParser(){};
~LLTextParser();
S32 findPattern(const std::string &text, LLSD highlight);
LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color,S32 part=WHOLE, S32 index=0);
LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color, EHighlightPosition part=WHOLE, S32 index=0);
bool parseFullLineHighlights(const std::string &text, LLColor4 *color);
std::string getFileName();

View File

@ -0,0 +1,82 @@
/**
* @file lltoggleablemenu.cpp
* @brief Menu toggled by a button press
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltoggleablemenu.h"
#include "lluictrlfactory.h"
static LLDefaultChildRegistry::Register<LLToggleableMenu> r("toggleable_menu");
LLToggleableMenu::LLToggleableMenu(const LLToggleableMenu::Params& p)
: LLMenuGL(p),
mClosedByButtonClick(false)
{
}
// virtual
void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn)
{
S32 x,y;
LLUI::getMousePositionLocal(LLUI::getRootView(), &x, &y);
if (!curVisibilityIn && mButtonRect.pointInRect(x, y))
{
mClosedByButtonClick = true;
}
}
void LLToggleableMenu::setButtonRect(const LLRect& rect, LLView* current_view)
{
LLRect screen;
current_view->localRectToScreen(rect, &screen);
mButtonRect = screen;
}
bool LLToggleableMenu::toggleVisibility()
{
if (mClosedByButtonClick)
{
mClosedByButtonClick = false;
return false;
}
if (getVisible())
{
setVisible(FALSE);
mClosedByButtonClick = false;
return false;
}
return true;
}

View File

@ -0,0 +1,65 @@
/**
* @file lltoggleablemenu.h
* @brief Menu toggled by a button press
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLTOGGLEABLEMENU_H
#define LL_LLTOGGLEABLEMENU_H
#include "llmenugl.h"
class LLToggleableMenu : public LLMenuGL
{
public:
//adding blank params to work around registration issue
//where LLToggleableMenu was owning the LLMenuGL param
//and menu.xml was never loaded
struct Params : public LLInitParam::Block<Params, LLMenuGL::Params>
{};
protected:
LLToggleableMenu(const Params&);
friend class LLUICtrlFactory;
public:
virtual void handleVisibilityChange (BOOL curVisibilityIn);
// Converts the given local button rect to a screen rect
void setButtonRect(const LLRect& rect, LLView* current_view);
// Returns "true" if menu was not closed by button click
// and is not still visible. If menu is visible toggles
// its visibility off.
bool toggleVisibility();
protected:
bool mClosedByButtonClick;
LLRect mButtonRect;
};
#endif // LL_LLTOGGLEABLEMENU_H

View File

@ -36,7 +36,6 @@
#include "lltooltip.h"
// Library includes
#include "llpanel.h"
#include "lltextbox.h"
#include "lliconctrl.h"
#include "llui.h" // positionViewNearMouse()
@ -45,7 +44,6 @@
//
// Constants
//
const F32 DELAY_BEFORE_SHOW_TIP = 0.35f;
//
// Local globals
@ -57,6 +55,11 @@ LLToolTipView *gToolTipView = NULL;
// Member functions
//
LLToolTipView::Params::Params()
{
mouse_opaque = false;
}
LLToolTipView::LLToolTipView(const LLToolTipView::Params& p)
: LLView(p)
{
@ -64,10 +67,7 @@ LLToolTipView::LLToolTipView(const LLToolTipView::Params& p)
void LLToolTipView::draw()
{
if (LLUI::getWindow()->isCursorHidden() )
{
LLToolTipMgr::instance().hideToolTips();
}
LLToolTipMgr::instance().updateToolTipVisibility();
// do the usual thing
LLView::draw();
@ -80,17 +80,10 @@ BOOL LLToolTipView::handleHover(S32 x, S32 y, MASK mask)
LLToolTipMgr& tooltip_mgr = LLToolTipMgr::instance();
// hide existing tooltips when mouse moves out of sticky rect
if (tooltip_mgr.toolTipVisible()
&& !tooltip_mgr.getStickyRect().pointInRect(x, y))
{
tooltip_mgr.hideToolTips();
}
// allow new tooltips whenever mouse moves
if (x != last_x && y != last_y)
{
tooltip_mgr.enableToolTips();
// allow new tooltips because mouse moved
tooltip_mgr.unblockToolTips();
}
last_x = x;
@ -100,96 +93,84 @@ BOOL LLToolTipView::handleHover(S32 x, S32 y, MASK mask)
BOOL LLToolTipView::handleMouseDown(S32 x, S32 y, MASK mask)
{
LLToolTipMgr::instance().hideToolTips();
LLToolTipMgr::instance().blockToolTips();
return LLView::handleMouseDown(x, y, mask);
}
BOOL LLToolTipView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
{
LLToolTipMgr::instance().hideToolTips();
LLToolTipMgr::instance().blockToolTips();
return LLView::handleMiddleMouseDown(x, y, mask);
}
BOOL LLToolTipView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
LLToolTipMgr::instance().hideToolTips();
LLToolTipMgr::instance().blockToolTips();
return LLView::handleRightMouseDown(x, y, mask);
}
BOOL LLToolTipView::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
LLToolTipMgr::instance().hideToolTips();
LLToolTipMgr::instance().blockToolTips();
return FALSE;
}
void LLToolTipView::onMouseLeave(S32 x, S32 y, MASK mask)
{
LLToolTipMgr::instance().hideToolTips();
LLToolTipMgr::instance().blockToolTips();
}
void LLToolTipView::drawStickyRect()
{
gl_rect_2d(LLToolTipMgr::instance().getStickyRect(), LLColor4::white, false);
gl_rect_2d(LLToolTipMgr::instance().getMouseNearRect(), LLColor4::white, false);
}
//
// LLToolTip
//
class LLToolTip : public LLPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Mandatory<F32> visible_time;
Optional<LLToolTipParams::click_callback_t> click_callback;
Optional<LLUIImage*> image;
Params()
{
//use_bounding_rect = true;
}
};
/*virtual*/ void draw();
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ void setValue(const LLSD& value);
/*virtual*/ void setVisible(BOOL visible);
bool isFading() { return mFadeTimer.getStarted(); }
LLToolTip(const Params& p);
private:
LLTextBox* mTextBox;
LLFrameTimer mFadeTimer;
F32 mVisibleTime;
bool mHasClickCallback;
};
static LLDefaultChildRegistry::Register<LLToolTip> r("tool_tip");
const S32 TOOLTIP_PADDING = 4;
LLToolTip::Params::Params()
: max_width("max_width", 200),
padding("padding", 4),
pos("pos"),
message("message"),
delay_time("delay_time", LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" )),
visible_time_over("visible_time_over", LLUI::sSettingGroups["config"]->getF32( "ToolTipVisibleTimeOver" )),
visible_time_near("visible_time_near", LLUI::sSettingGroups["config"]->getF32( "ToolTipVisibleTimeNear" )),
visible_time_far("visible_time_far", LLUI::sSettingGroups["config"]->getF32( "ToolTipVisibleTimeFar" )),
sticky_rect("sticky_rect"),
image("image")
{
name = "tooltip";
font = LLFontGL::getFontSansSerif();
bg_opaque_color = LLUIColorTable::instance().getColor( "ToolTipBgColor" );
background_visible = true;
}
LLToolTip::LLToolTip(const LLToolTip::Params& p)
: LLPanel(p),
mVisibleTime(p.visible_time),
mHasClickCallback(p.click_callback.isProvided())
mMaxWidth(p.max_width),
mHasClickCallback(p.click_callback.isProvided()),
mPadding(p.padding)
{
LLTextBox::Params params;
params.text = "tip_text";
params.name = params.text;
params.initial_value = "tip_text";
params.name = params.initial_value().asString();
// bake textbox padding into initial rect
params.rect = LLRect (TOOLTIP_PADDING, TOOLTIP_PADDING + 1, TOOLTIP_PADDING + 1, TOOLTIP_PADDING);
params.rect = LLRect (mPadding, mPadding + 1, mPadding + 1, mPadding);
params.follows.flags = FOLLOWS_ALL;
params.h_pad = 4;
params.v_pad = 2;
params.h_pad = 0;
params.v_pad = 0;
params.mouse_opaque = false;
params.text_color = LLUIColorTable::instance().getColor( "ToolTipTextColor" );
params.bg_visible = false;
params.font.style = "NORMAL";
//params.border_drop_shadow_visible = true;
params.font = p.font;
params.use_ellipses = true;
mTextBox = LLUICtrlFactory::create<LLTextBox> (params);
addChild(mTextBox);
@ -198,8 +179,9 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
LLIconCtrl::Params icon_params;
icon_params.name = "tooltip_icon";
LLRect icon_rect;
const S32 TOOLTIP_ICON_SIZE = 18;
icon_rect.setOriginAndSize(TOOLTIP_PADDING, TOOLTIP_PADDING, TOOLTIP_ICON_SIZE, TOOLTIP_ICON_SIZE);
LLUIImage* imagep = p.image;
const S32 TOOLTIP_ICON_SIZE = (imagep ? imagep->getWidth() : 16);
icon_rect.setOriginAndSize(mPadding, mPadding, TOOLTIP_ICON_SIZE, TOOLTIP_ICON_SIZE);
icon_params.rect = icon_rect;
icon_params.follows.flags = FOLLOWS_LEFT | FOLLOWS_BOTTOM;
icon_params.image = p.image;
@ -218,13 +200,20 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
void LLToolTip::setValue(const LLSD& value)
{
mTextBox->setWrappedText(value.asString());
mTextBox->reshapeToFitText();
const S32 REALLY_LARGE_HEIGHT = 10000;
reshape(mMaxWidth, REALLY_LARGE_HEIGHT);
mTextBox->setValue(value);
LLRect text_contents_rect = mTextBox->getContentsRect();
S32 text_width = llmin(mMaxWidth, text_contents_rect.getWidth());
S32 text_height = text_contents_rect.getHeight();
mTextBox->reshape(text_width, text_height);
// reshape tooltip panel to fit text box
LLRect tooltip_rect = calcBoundingRect();
tooltip_rect.mTop += TOOLTIP_PADDING;
tooltip_rect.mRight += TOOLTIP_PADDING;
tooltip_rect.mTop += mPadding;
tooltip_rect.mRight += mPadding;
tooltip_rect.mBottom = 0;
tooltip_rect.mLeft = 0;
@ -234,19 +223,21 @@ void LLToolTip::setValue(const LLSD& value)
void LLToolTip::setVisible(BOOL visible)
{
// fade out tooltip over time
if (!visible)
if (visible)
{
mVisibleTimer.start();
mFadeTimer.stop();
LLPanel::setVisible(TRUE);
}
else
{
mVisibleTimer.stop();
// don't actually change mVisible state, start fade out transition instead
if (!mFadeTimer.getStarted())
{
mFadeTimer.start();
}
}
else
{
mFadeTimer.stop();
LLPanel::setVisible(TRUE);
}
}
BOOL LLToolTip::handleHover(S32 x, S32 y, MASK mask)
@ -263,11 +254,6 @@ void LLToolTip::draw()
{
F32 alpha = 1.f;
if (LLUI::getMouseIdleTime() > mVisibleTime)
{
LLToolTipMgr::instance().hideToolTips();
}
if (mFadeTimer.getStarted())
{
F32 tool_tip_fade_time = LLUI::sSettingGroups["config"]->getF32("ToolTipFadeTime");
@ -287,94 +273,90 @@ void LLToolTip::draw()
}
}
bool LLToolTip::isFading()
{
return mFadeTimer.getStarted();
}
F32 LLToolTip::getVisibleTime()
{
return mVisibleTimer.getStarted() ? mVisibleTimer.getElapsedTimeF32() : 0.f;
}
bool LLToolTip::hasClickCallback()
{
return mHasClickCallback;
}
//
// LLToolTipMgr
//
LLToolTipParams::LLToolTipParams()
: pos("pos"),
message("message"),
delay_time("delay_time", LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" )),
visible_time("visible_time", LLUI::sSettingGroups["config"]->getF32( "ToolTipVisibleTime" )),
sticky_rect("sticky_rect"),
width("width", 200),
image("image")
{}
LLToolTipMgr::LLToolTipMgr()
: mToolTip(NULL)
: mToolTip(NULL),
mNeedsToolTip(false)
{}
void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
{
}
// block all other tooltips until tooltips re-enabled (e.g. mouse moved)
blockToolTips();
LLToolTip* LLToolTipMgr::createToolTip(const LLToolTipParams& params)
{
S32 mouse_x;
S32 mouse_y;
LLUI::getMousePositionLocal(gToolTipView->getParent(), &mouse_x, &mouse_y);
delete mToolTip;
LLToolTip::Params tooltip_params;
tooltip_params.name = "tooltip";
tooltip_params.mouse_opaque = true;
LLToolTip::Params tooltip_params(params);
// block mouse events if there is a click handler registered (specifically, hover)
tooltip_params.mouse_opaque = params.click_callback.isProvided();
tooltip_params.rect = LLRect (0, 1, 1, 0);
tooltip_params.bg_opaque_color = LLUIColorTable::instance().getColor( "ToolTipBgColor" );
tooltip_params.background_visible = true;
tooltip_params.visible_time = params.visible_time;
if (params.image.isProvided())
{
tooltip_params.image = params.image;
}
if (params.click_callback.isProvided())
{
tooltip_params.click_callback = params.click_callback;
}
LLToolTip* tooltip = LLUICtrlFactory::create<LLToolTip> (tooltip_params);
// make tooltip fixed width and tall enough to fit text
tooltip->reshape(params.width, 2000);
tooltip->setValue(params.message());
gToolTipView->addChild(tooltip);
mToolTip = LLUICtrlFactory::create<LLToolTip> (tooltip_params);
mToolTip->setValue(params.message());
gToolTipView->addChild(mToolTip);
if (params.pos.isProvided())
{
LLCoordGL pos = params.pos;
// try to spawn at requested position
LLUI::positionViewNearMouse(tooltip, params.pos.x, params.pos.y);
LLUI::positionViewNearMouse(mToolTip, pos.mX, pos.mY);
}
else
{
// just spawn at mouse location
LLUI::positionViewNearMouse(tooltip);
LLUI::positionViewNearMouse(mToolTip);
}
//...update "sticky" rect and tooltip position
if (params.sticky_rect.isProvided())
{
mToolTipStickyRect = params.sticky_rect;
mMouseNearRect = params.sticky_rect;
}
else
{
// otherwise just use one pixel rect around mouse cursor
mToolTipStickyRect.setOriginAndSize(mouse_x, mouse_y, 1, 1);
}
if (params.click_callback.isProvided())
{
// keep tooltip up when we mouse over it
mToolTipStickyRect.unionWith(tooltip->getRect());
S32 mouse_x;
S32 mouse_y;
LLUI::getMousePositionLocal(gToolTipView->getParent(), &mouse_x, &mouse_y);
// allow mouse a little bit of slop before changing tooltips
mMouseNearRect.setCenterAndSize(mouse_x, mouse_y, 3, 3);
}
return tooltip;
// allow mouse to move all the way to the tooltip without changing tooltips
// (tooltip can still time out)
if (mToolTip->hasClickCallback())
{
// keep tooltip up when we mouse over it
mMouseNearRect.unionWith(mToolTip->getRect());
}
}
void LLToolTipMgr::show(const std::string& msg)
{
show(LLToolTipParams().message(msg));
show(LLToolTip::Params().message(msg));
}
void LLToolTipMgr::show(const LLToolTipParams& params)
void LLToolTipMgr::show(const LLToolTip::Params& params)
{
if (!params.validateBlock())
{
@ -382,38 +364,42 @@ void LLToolTipMgr::show(const LLToolTipParams& params)
return;
}
bool tooltip_shown = mToolTip
&& mToolTip->getVisible()
&& !mToolTip->isFading();
// if tooltip contents change, hide existing tooltip
if (tooltip_shown && mLastToolTipMessage != params.message())
{
hideToolTips();
}
S32 mouse_x;
S32 mouse_y;
LLUI::getMousePositionLocal(gToolTipView, &mouse_x, &mouse_y);
// are we ready to show the tooltip?
if (!mToolTipsBlocked // we haven't hit a key, moved the mouse, etc.
&& LLUI::getMouseIdleTime() > params.delay_time // the mouse has been still long enough
&& !tooltip_shown) // tooltip not visible
&& LLUI::getMouseIdleTime() > params.delay_time) // the mouse has been still long enough
{
// create new tooltip at mouse cursor position
delete mToolTip;
mToolTip = createToolTip(params);
bool tooltip_changed = mLastToolTipParams.message() != params.message()
|| mLastToolTipParams.pos() != params.pos();
// remember this tooltip so we know when it changes
mLastToolTipMessage = params.message();
bool tooltip_shown = mToolTip
&& mToolTip->getVisible()
&& !mToolTip->isFading();
mNeedsToolTip = tooltip_changed || !tooltip_shown;
// store description of tooltip for later creation
mNextToolTipParams = params;
}
}
// allow new tooltips to be created, e.g. after mouse has moved
void LLToolTipMgr::enableToolTips()
void LLToolTipMgr::unblockToolTips()
{
mToolTipsBlocked = false;
}
// disallow new tooltips until unblockTooltips called
void LLToolTipMgr::blockToolTips()
{
hideToolTips();
mToolTipsBlocked = true;
}
void LLToolTipMgr::hideToolTips()
{
mToolTipsBlocked = true;
if (mToolTip)
{
mToolTip->setVisible(FALSE);
@ -422,7 +408,7 @@ void LLToolTipMgr::hideToolTips()
bool LLToolTipMgr::toolTipVisible()
{
return mToolTip ? mToolTip->getVisible() : false;
return mToolTip ? mToolTip->isInVisibleChain() : false;
}
LLRect LLToolTipMgr::getToolTipRect()
@ -435,11 +421,63 @@ LLRect LLToolTipMgr::getToolTipRect()
}
LLRect LLToolTipMgr::getStickyRect()
LLRect LLToolTipMgr::getMouseNearRect()
{
if (!mToolTip) return LLRect();
return mToolTip->isInVisibleChain() ? mToolTipStickyRect : LLRect();
return toolTipVisible() ? mMouseNearRect : LLRect();
}
// every frame, determine if current tooltip should be hidden
void LLToolTipMgr::updateToolTipVisibility()
{
// create new tooltip if we have one ready to go
if (mNeedsToolTip)
{
mNeedsToolTip = false;
createToolTip(mNextToolTipParams);
mLastToolTipParams = mNextToolTipParams;
return;
}
// hide tooltips when mouse cursor is hidden
if (LLUI::getWindow()->isCursorHidden())
{
blockToolTips();
return;
}
// hide existing tooltips if they have timed out
S32 mouse_x, mouse_y;
LLUI::getMousePositionLocal(gToolTipView, &mouse_x, &mouse_y);
F32 tooltip_timeout = 0.f;
if (toolTipVisible())
{
// mouse far away from tooltip
tooltip_timeout = mLastToolTipParams.visible_time_far;
// mouse near rect will only include the tooltip if the
// tooltip is clickable
if (mMouseNearRect.pointInRect(mouse_x, mouse_y))
{
// mouse "close" to tooltip
tooltip_timeout = mLastToolTipParams.visible_time_near;
// if tooltip is clickable (has large mMouseNearRect)
// than having cursor over tooltip keeps it up indefinitely
if (mToolTip->parentPointInView(mouse_x, mouse_y))
{
// mouse over tooltip itself, don't time out
tooltip_timeout = mLastToolTipParams.visible_time_over;
}
}
if (mToolTip->getVisibleTime() > tooltip_timeout)
{
hideToolTips();
}
}
}
// EOF

View File

@ -36,7 +36,7 @@
// Library includes
#include "llsingleton.h"
#include "llinitparam.h"
#include "llview.h"
#include "llpanel.h"
//
// Classes
@ -46,10 +46,7 @@ class LLToolTipView : public LLView
public:
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
Params()
{
mouse_opaque = false;
}
Params();
};
LLToolTipView(const LLToolTipView::Params&);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
@ -65,57 +62,82 @@ public:
/*virtual*/ void draw();
};
struct LLToolTipPosParams : public LLInitParam::Block<LLToolTipPosParams>
class LLToolTip : public LLPanel
{
Mandatory<S32> x,
y;
LLToolTipPosParams()
: x("x"),
y("y")
{}
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
typedef boost::function<void(void)> click_callback_t;
Mandatory<std::string> message;
Optional<LLCoordGL> pos;
Optional<F32> delay_time,
visible_time_over, // time for which tooltip is visible while mouse on it
visible_time_near, // time for which tooltip is visible while mouse near it
visible_time_far; // time for which tooltip is visible while mouse moved away
Optional<LLRect> sticky_rect;
Optional<const LLFontGL*> font;
Optional<click_callback_t> click_callback;
Optional<LLUIImage*> image;
Optional<S32> max_width;
Optional<S32> padding;
Params();
};
/*virtual*/ void draw();
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ void setValue(const LLSD& value);
/*virtual*/ void setVisible(BOOL visible);
bool isFading();
F32 getVisibleTime();
bool hasClickCallback();
LLToolTip(const Params& p);
private:
class LLTextBox* mTextBox;
LLFrameTimer mFadeTimer;
LLFrameTimer mVisibleTimer;
S32 mMaxWidth;
bool mHasClickCallback;
S32 mPadding; // pixels
};
struct LLToolTipParams : public LLInitParam::Block<LLToolTipParams>
{
typedef boost::function<void(void)> click_callback_t;
Mandatory<std::string> message;
Optional<LLToolTipPosParams> pos;
Optional<F32> delay_time,
visible_time;
Optional<LLRect> sticky_rect;
Optional<S32> width;
Optional<LLUIImage*> image;
Optional<click_callback_t> click_callback;
LLToolTipParams();
LLToolTipParams(const std::string& message);
};
class LLToolTipMgr : public LLSingleton<LLToolTipMgr>
{
LOG_CLASS(LLToolTipMgr);
public:
LLToolTipMgr();
void show(const LLToolTipParams& params);
void show(const LLToolTip::Params& params);
void show(const std::string& message);
void enableToolTips();
void unblockToolTips();
void blockToolTips();
void hideToolTips();
bool toolTipVisible();
LLRect getToolTipRect();
LLRect getStickyRect();
LLRect getMouseNearRect();
void updateToolTipVisibility();
private:
class LLToolTip* createToolTip(const LLToolTipParams& params);
void createToolTip(const LLToolTip::Params& params);
bool mToolTipsBlocked;
class LLToolTip* mToolTip;
std::string mLastToolTipMessage;
LLRect mToolTipStickyRect;
// tooltip creation is deferred until the UI is drawn every frame
// so the last tooltip to be created in a given frame will win
LLToolTip::Params mLastToolTipParams; // description of last tooltip we showed
LLToolTip::Params mNextToolTipParams; // description of next tooltip we want to show
bool mNeedsToolTip; // do we want to show a tooltip
LLRect mMouseNearRect;
};
//

View File

@ -55,6 +55,7 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "llmenugl.h"
#include "llmenubutton.h"
#include "llwindow.h"
// for registration
@ -90,6 +91,7 @@ std::list<std::string> gUntranslated;
static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor");
static LLDefaultChildRegistry::Register<LLFlyoutButton> register_flyout_button("flyout_button");
static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("search_editor");
static LLDefaultChildRegistry::Register<LLMenuButton> register_menu_button("menu_button");
//
@ -1643,6 +1645,17 @@ void LLUI::setMousePositionScreen(S32 x, S32 y)
LLView::getWindow()->setCursorPosition(window_point);
}
//static
void LLUI::getMousePositionScreen(S32 *x, S32 *y)
{
LLCoordWindow cursor_pos_window;
getWindow()->getCursorPosition(&cursor_pos_window);
LLCoordGL cursor_pos_gl;
getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
*x = llround((F32)cursor_pos_gl.mX / sGLScaleFactor.mV[VX]);
*y = llround((F32)cursor_pos_gl.mY / sGLScaleFactor.mV[VX]);
}
//static
void LLUI::setMousePositionLocal(const LLView* viewp, S32 x, S32 y)
{
@ -1655,15 +1668,12 @@ void LLUI::setMousePositionLocal(const LLView* viewp, S32 x, S32 y)
//static
void LLUI::getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y)
{
LLCoordWindow cursor_pos_window;
LLView::getWindow()->getCursorPosition(&cursor_pos_window);
LLCoordGL cursor_pos_gl;
LLView::getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]);
cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]);
viewp->screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, x, y);
S32 screen_x, screen_y;
getMousePositionScreen(&screen_x, &screen_y);
viewp->screenPointToLocal(screen_x, screen_y, x, y);
}
// On Windows, the user typically sets the language when they install the
// app (by running it with a shortcut that sets InstallLanguage). On Mac,
// or on Windows if the SecondLife.exe executable is run directly, the
@ -1835,14 +1845,14 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
// spawn_x and spawn_y are top left corner of view in screen GL coordinates
void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)
{
const S32 CURSOR_HEIGHT = 22; // Approximate "normal" cursor size
const S32 CURSOR_WIDTH = 12;
const S32 CURSOR_HEIGHT = 18; // Approximate "normal" cursor size
const S32 CURSOR_WIDTH = 9;
LLView* parent = view->getParent();
S32 mouse_x;
S32 mouse_y;
LLUI::getMousePositionLocal(parent, &mouse_x, &mouse_y);
LLUI::getMousePositionScreen(&mouse_x, &mouse_y);
// If no spawn location provided, use mouse position
if (spawn_x == S32_MAX || spawn_y == S32_MAX)
@ -1856,12 +1866,13 @@ void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y)
LLRect mouse_rect;
const S32 MOUSE_CURSOR_PADDING = 5;
mouse_rect.setLeftTopAndSize(mouse_x - MOUSE_CURSOR_PADDING,
mouse_y + MOUSE_CURSOR_PADDING,
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
mouse_y + MOUSE_CURSOR_PADDING,
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
S32 local_x, local_y;
view->getParent()->screenPointToLocal(spawn_x, spawn_y, &local_x, &local_y);
// convert screen coordinates to tooltipview-local coordinates
parent->screenPointToLocal(spawn_x, spawn_y, &local_x, &local_y);
// Start at spawn position (using left/top)
view->setOrigin( local_x, local_y - view->getRect().getHeight());
@ -1915,12 +1926,14 @@ namespace LLInitParam
}
};
TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
: super_t(descriptor, name, value, func, min_count, max_count),
name(""),
TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
: super_t(descriptor, _name, value, func, min_count, max_count),
name("name"),
size("size"),
style("style")
{}
{
addSynonym(name, "");
}
const LLFontGL* TypedParam<const LLFontGL*>::getValueFromBlock() const
{

View File

@ -190,6 +190,7 @@ public:
static void setRootView(LLView* view) { sRootView = view; }
static std::string locateSkin(const std::string& filename);
static void setMousePositionScreen(S32 x, S32 y);
static void getMousePositionScreen(S32 *x, S32 *y);
static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
static void setScaleFactor(const LLVector2& scale_factor);
@ -409,8 +410,8 @@ namespace LLInitParam
{
typedef BlockValue<const LLFontGL*> super_t;
public:
Optional<std::string> name,
size,
Mandatory<std::string> name;
Optional<std::string> size,
style;
TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);

View File

@ -49,7 +49,12 @@ LLUICtrl::Params::Params()
validate_callback("validate_callback"),
mouseenter_callback("mouseenter_callback"),
mouseleave_callback("mouseleave_callback"),
control_name("control_name")
control_name("control_name"),
font("font", LLFontGL::getFontSansSerif()),
font_halign("halign"),
font_valign("valign"),
length("length"), // ignore LLXMLNode cruft
type("type") // ignore LLXMLNode cruft
{
addSynonym(initial_value, "initial_value");
}
@ -212,6 +217,29 @@ void LLUICtrl::initEnableCallback(const EnableCallbackParam& cb, enable_signal_t
}
}
void LLUICtrl::initVisibleCallback(const VisibleCallbackParam& cb, visible_signal_t& sig)
{
// Set the callback function
if (cb.function.isProvided())
{
if (cb.parameter.isProvided())
sig.connect(boost::bind(cb.function(), this, cb.parameter));
else
sig.connect(cb.function());
}
else
{
visible_callback_t* func = (VisibleCallbackRegistry::getValue(cb.function_name));
if (func)
{
if (cb.parameter.isProvided())
sig.connect(boost::bind((*func), this, cb.parameter));
else
sig.connect(*func);
}
}
}
// virtual
void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask)
{

View File

@ -34,14 +34,15 @@
#ifndef LL_LLUICTRL_H
#define LL_LLUICTRL_H
#include "llboost.h"
//#include "llboost.h"
#include "llrect.h"
#include "llsd.h"
#include <boost/function.hpp>
#include <boost/signals2.hpp>
#include "llinitparam.h"
#include "llview.h"
#include "llviewmodel.h"
#include "llviewmodel.h" // *TODO move dependency to .cpp file
const BOOL TAKE_FOCUS_YES = TRUE;
const BOOL TAKE_FOCUS_NO = FALSE;
@ -62,6 +63,9 @@ public:
typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> enable_callback_t;
typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t;
typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> visible_callback_t;
typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> visible_signal_t;
struct CallbackParam : public LLInitParam::Block<CallbackParam>
{
Ignored name;
@ -91,6 +95,11 @@ public:
Optional<enable_callback_t> function;
};
struct VisibleCallbackParam : public LLInitParam::Block<VisibleCallbackParam, CallbackParam >
{
Optional<visible_callback_t> function;
};
struct EnableControls : public LLInitParam::Choice<EnableControls>
{
Alternative<std::string> enabled;
@ -107,9 +116,12 @@ public:
Alternative<std::string> invisible;
ControlVisibility()
: visible("visiblity_control"),
invisible("invisiblity_control")
{}
: visible("visibility_control"),
invisible("invisibility_control")
{
addSynonym(visible, "visiblity_control");
addSynonym(invisible, "invisiblity_control");
}
};
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
@ -128,6 +140,15 @@ public:
Optional<EnableControls> enabled_controls;
Optional<ControlVisibility> controls_visibility;
// font params
Optional<const LLFontGL*> font;
Optional<LLFontGL::HAlign> font_halign;
Optional<LLFontGL::VAlign> font_valign;
// cruft from LLXMLNode implementation
Ignored type,
length;
Params();
};
@ -142,6 +163,7 @@ protected:
void initCommitCallback(const CommitCallbackParam& cb, commit_signal_t& sig);
void initEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig);
void initVisibleCallback(const VisibleCallbackParam& cb, visible_signal_t& sig);
// We need this virtual so we can override it with derived versions
virtual LLViewModel* getViewModel() const;
@ -259,6 +281,8 @@ public:
class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{};
class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{};
class VisibleCallbackRegistry : public CallbackRegistry<visible_callback_t, VisibleCallbackRegistry>{};
protected:

View File

@ -113,8 +113,20 @@ void LLUICtrlFactory::createChildren(LLView* viewp, LLXMLNodePtr node, const wid
if (!instance().createFromXML(child_node, viewp, LLStringUtil::null, registry, outputChild))
{
// child_node is not a valid child for the current parent
std::string child_name = std::string(child_node->getName()->mString);
llwarns << "Could not create widget named " << child_node->getName()->mString << llendl;
if (LLDefaultChildRegistry::instance().getValue(child_name))
{
// This means that the registry assocaited with the parent widget does not have an entry
// for the child widget
// You might need to add something like:
// static ParentWidgetRegistry::Register<ChildWidgetType> register("child_widget_name");
llwarns << child_name << " is not a valid child of " << node->getName()->mString << llendl;
}
else
{
llwarns << "Could not create widget named " << child_node->getName()->mString << llendl;
}
}
if (outputChild && !outputChild->mChildren && outputChild->mAttributes.empty() && outputChild->getValue().empty())

View File

@ -36,8 +36,10 @@
#include "lluri.h"
#include "llcachename.h"
#include "lltrans.h"
#include "lluicolortable.h"
LLUrlEntryBase::LLUrlEntryBase()
: mColor(LLUIColorTable::instance().getColor("HTMLLinkColor"))
{
}
@ -260,10 +262,11 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
//
LLUrlEntryAgent::LLUrlEntryAgent()
{
mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/about",
mPattern = boost::regex("secondlife:///app/agent/[\\da-f-]+/\\w+",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_agent.xml";
mTooltip = LLTrans::getString("TooltipAgentUrl");
mIcon = "Generic_Person";
mColor = LLUIColorTable::instance().getColor("AgentLinkColor");
}
void LLUrlEntryAgent::onAgentNameReceived(const LLUUID& id,
@ -293,7 +296,7 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
}
}
return unescapeUrl(url);
return LLTrans::getString("LoadingData");//unescapeUrl(url);
}
//
@ -305,6 +308,7 @@ LLUrlEntryGroup::LLUrlEntryGroup()
mPattern = boost::regex("secondlife:///app/group/[\\da-f-]+/about",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_group.xml";
mIcon = "Generic_Group";
mTooltip = LLTrans::getString("TooltipGroupUrl");
}

View File

@ -35,7 +35,7 @@
#define LL_LLURLENTRY_H
#include "lluuid.h"
#include "lluicolor.h"
#include <boost/signals2.hpp>
#include <boost/regex.hpp>
#include <string>
@ -77,13 +77,16 @@ public:
virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; }
/// Return an icon that can be displayed next to Urls of this type
const std::string &getIcon() const { return mIcon; }
std::string getIcon() const { return mIcon; }
/// Return the color to render the displayed text
LLUIColor getColor() const { return mColor; }
/// Given a matched Url, return a tooltip string for the hyperlink
std::string getTooltip() const { return mTooltip; }
/// Return the name of a XUI file containing the context menu items
const std::string getMenuName() const { return mMenuName; }
std::string getMenuName() const { return mMenuName; }
/// Return the name of a SL location described by this Url, if any
virtual std::string getLocation(const std::string &url) const { return ""; }
@ -102,11 +105,12 @@ protected:
LLUrlLabelSignal *signal;
} LLUrlEntryObserver;
boost::regex mPattern;
std::string mIcon;
std::string mMenuName;
std::string mTooltip;
std::multimap<std::string, LLUrlEntryObserver> mObservers;
boost::regex mPattern;
std::string mIcon;
std::string mMenuName;
std::string mTooltip;
LLUIColor mColor;
std::multimap<std::string, LLUrlEntryObserver> mObservers;
};
///

View File

@ -47,8 +47,8 @@ LLUrlMatch::LLUrlMatch() :
void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
const std::string &label, const std::string &tooltip,
const std::string &icon, const std::string &menu,
const std::string &location)
const std::string &icon, const LLUIColor& color,
const std::string &menu, const std::string &location)
{
mStart = start;
mEnd = end;
@ -56,6 +56,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
mLabel = label;
mTooltip = tooltip;
mIcon = icon;
mColor = color;
mMenuName = menu;
mLocation = location;
}

View File

@ -38,6 +38,7 @@
#include <string>
#include <vector>
#include "lluicolor.h"
///
/// LLUrlMatch describes a single Url that was matched within a string by
@ -62,27 +63,31 @@ public:
U32 getEnd() const { return mEnd; }
/// return the Url that has been matched in the input string
const std::string &getUrl() const { return mUrl; }
std::string getUrl() const { return mUrl; }
/// return a label that can be used for the display of this Url
const std::string &getLabel() const { return mLabel; }
std::string getLabel() const { return mLabel; }
/// return a message that could be displayed in a tooltip or status bar
const std::string &getTooltip() const { return mTooltip; }
std::string getTooltip() const { return mTooltip; }
/// return the filename for an icon that can be displayed next to this Url
const std::string &getIcon() const { return mIcon; }
std::string getIcon() const { return mIcon; }
/// Return the color to render the displayed text
LLUIColor getColor() const { return mColor; }
/// Return the name of a XUI file containing the context menu items
const std::string getMenuName() const { return mMenuName; }
std::string getMenuName() const { return mMenuName; }
/// return the SL location that this Url describes, or "" if none.
const std::string &getLocation() const { return mLocation; }
std::string getLocation() const { return mLocation; }
/// Change the contents of this match object (used by LLUrlRegistry)
void setValues(U32 start, U32 end, const std::string &url, const std::string &label,
const std::string &tooltip, const std::string &icon,
const std::string &menu, const std::string &location);
const LLUIColor& color, const std::string &menu,
const std::string &location);
private:
U32 mStart;
@ -93,6 +98,7 @@ private:
std::string mIcon;
std::string mMenuName;
std::string mLocation;
LLUIColor mColor;
};
#endif

View File

@ -155,6 +155,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getLabel(url, cb),
match_entry->getTooltip(),
match_entry->getIcon(),
match_entry->getColor(),
match_entry->getMenuName(),
match_entry->getLocation(url));
return true;
@ -183,9 +184,10 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
}
S32 end = start + wurl.size() - 1;
match.setValues(start, end, match.getUrl(), match.getLabel(),
match.getTooltip(), match.getIcon(),
match.getMenuName(), match.getLocation());
match.setValues(start, end, match.getUrl(),
match.getLabel(), match.getTooltip(),
match.getIcon(), match.getColor(),
match.getMenuName(), match.getLocation());
return true;
}
return false;

View File

@ -92,9 +92,6 @@ LLView::Params::Params()
default_tab_group("default_tab_group"),
tool_tip("tool_tip"),
sound_flags("sound_flags", MOUSE_UP),
font("font", LLFontGL::getFontSansSerif()),
font_halign("halign"),
font_valign("valign"),
layout("layout"),
rect("rect"),
bottom_delta("bottom_delta", S32_MAX),
@ -171,12 +168,6 @@ LLView::~LLView()
}
}
// virtual
BOOL LLView::isView() const
{
return TRUE;
}
// virtual
BOOL LLView::isCtrl() const
{
@ -227,10 +218,9 @@ BOOL LLView::getUseBoundingRect()
}
// virtual
const std::string& LLView::getName() const
std::string LLView::getName() const
{
static const std::string unnamed("(no name)");
return mName.empty() ? unnamed : mName;
return mName.empty() ? std::string("(no name)") : mName;
}
void LLView::sendChildToFront(LLView* child)
@ -634,16 +624,7 @@ void LLView::setSnappedTo(const LLView* snap_view)
BOOL LLView::handleHover(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleHover( x, y, mask ) != NULL;
if( !handled
&& blockMouseEvent(x, y) )
{
LLUI::sWindow->setCursor(mHoverCursor);
lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
handled = TRUE;
}
return handled;
return childrenHandleHover( x, y, mask ) != NULL;
}
void LLView::onMouseEnter(S32 x, S32 y, MASK mask)
@ -657,7 +638,7 @@ void LLView::onMouseLeave(S32 x, S32 y, MASK mask)
}
LLView* LLView::childrenHandleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
LLView* LLView::childrenHandleToolTip(S32 x, S32 y, MASK mask)
{
LLView* handled_view = NULL;
for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
@ -665,13 +646,13 @@ LLView* LLView::childrenHandleToolTip(S32 x, S32 y, std::string& msg, LLRect& st
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if(!viewp->pointInView(local_x, local_y) ||
!viewp->getVisible())
if(!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible())
{
continue;
}
if(viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen) )
if (viewp->handleToolTip(local_x, local_y, mask) )
{
if (sDebugMouseHandling)
{
@ -682,20 +663,22 @@ LLView* LLView::childrenHandleToolTip(S32 x, S32 y, std::string& msg, LLRect& st
break;
}
if( viewp->blockMouseEvent(x, y) )
if (viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
return handled_view;
}
BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
// parents provide tooltips first, which are optionally
// overridden by children
// overridden by children, in case child is mouse_opaque
if (!mToolTipMsg.empty())
{
// allow "scrubbing" over ui by showing next tooltip immediately
@ -703,7 +686,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_s
F32 timeout = LLToolTipMgr::instance().toolTipVisible()
? 0.f
: LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
LLToolTipMgr::instance().show(LLToolTipParams()
LLToolTipMgr::instance().show(LLToolTip::Params()
.message(mToolTipMsg)
.sticky_rect(calcScreenRect())
.delay_time(timeout));
@ -712,7 +695,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_s
}
// child tooltips will override our own
LLView* child_handler = childrenHandleToolTip(x, y, msg, sticky_rect_screen);
LLView* child_handler = childrenHandleToolTip(x, y, mask);
if (child_handler)
{
handled = TRUE;
@ -720,7 +703,6 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_s
return handled;
}
BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
BOOL handled = FALSE;
@ -801,20 +783,7 @@ BOOL LLView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EAcceptance* accept,
std::string& tooltip_msg)
{
// CRO this is an experiment to allow drag and drop into object inventory based on the DragAndDrop tool's permissions rather than the parent
BOOL handled = childrenHandleDragAndDrop( x, y, mask, drop,
cargo_type,
cargo_data,
accept,
tooltip_msg) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
*accept = ACCEPT_NO;
handled = TRUE;
lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLView " << getName() << llendl;
}
return handled;
return childrenHandleDragAndDrop( x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL;
}
LLView* LLView::childrenHandleDragAndDrop(S32 x, S32 y, MASK mask,
@ -824,28 +793,33 @@ LLView* LLView::childrenHandleDragAndDrop(S32 x, S32 y, MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
LLView* handled_view = FALSE;
// CRO this is an experiment to allow drag and drop into object inventory based on the DragAndDrop tool's permissions rather than the parent
if( getVisible() )
// if( getVisible() && getEnabled() )
LLView* handled_view = NULL;
for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
{
for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if( !viewp->pointInView(local_x, local_y) ||
!viewp->getVisible() ||
!viewp->getEnabled())
{
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if( viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleDragAndDrop(local_x, local_y, mask, drop,
cargo_type,
cargo_data,
accept,
tooltip_msg))
{
handled_view = viewp;
break;
}
continue;
}
if (viewp->handleDragAndDrop(local_x, local_y, mask, drop,
cargo_type,
cargo_data,
accept,
tooltip_msg))
{
handled_view = viewp;
break;
}
if (viewp->blockMouseEvent(x, y))
{
*accept = ACCEPT_NO;
handled_view = viewp;
break;
}
}
return handled_view;
@ -862,105 +836,42 @@ BOOL LLView::hasMouseCapture()
BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleMouseUp( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
return handled;
return childrenHandleMouseUp( x, y, mask ) != NULL;
}
BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
{
LLView* handled_view = childrenHandleMouseDown( x, y, mask );
BOOL handled = (handled_view != NULL);
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
handled_view = this;
}
//// HACK If we're editing UI, select the leaf view that ate the click.
//if (sEditingUI && handled_view)
//{
// // need to find leaf views, big hack
// LLButton* buttonp = dynamic_cast<LLButton*>(handled_view);
// LLLineEditor* line_editorp = dynamic_cast<LLLineEditor*>(handled_view);
// LLTextEditor* text_editorp = dynamic_cast<LLTextEditor*>(handled_view);
// LLTextBox* text_boxp = dynamic_cast<LLTextBox*>(handled_view);
// if (buttonp
// || line_editorp
// || text_editorp
// || text_boxp)
// {
// sEditingUIView = handled_view;
// }
//}
return handled;
return childrenHandleMouseDown( x, y, mask ) != NULL;
}
BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handleMouseDown(x, y, mask);
handled = TRUE;
}
return handled;
return childrenHandleDoubleClick( x, y, mask ) != NULL;
}
BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
if( getVisible() && getEnabled() )
{
return childrenHandleScrollWheel( x, y, clicks ) != NULL;
}
return FALSE;
return childrenHandleScrollWheel( x, y, clicks ) != NULL;
}
BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
return handled;
return childrenHandleRightMouseDown( x, y, mask ) != NULL;
}
BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleRightMouseUp( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
return handled;
return childrenHandleRightMouseUp( x, y, mask ) != NULL;
}
BOOL LLView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
{
LLView* handled_view = childrenHandleMiddleMouseDown( x, y, mask );
BOOL handled = (handled_view != NULL);
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
handled_view = this;
}
return handled;
return childrenHandleMiddleMouseDown( x, y, mask ) != NULL;
}
BOOL LLView::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleMiddleMouseUp( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
return handled;
return childrenHandleMiddleMouseUp( x, y, mask ) != NULL;
}
@ -974,10 +885,14 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y)
&& viewp->getVisible()
&& viewp->getEnabled()
&& viewp->handleScrollWheel( local_x, local_y, clicks ))
if (!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled())
{
continue;
}
if (viewp->handleScrollWheel( local_x, local_y, clicks ))
{
if (sDebugMouseHandling)
{
@ -987,6 +902,12 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks)
handled_view = viewp;
break;
}
if (viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
}
return handled_view;
@ -1002,10 +923,14 @@ LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if(viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleHover(local_x, local_y, mask) )
if(!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled())
{
continue;
}
if (viewp->handleHover(local_x, local_y, mask) )
{
if (sDebugMouseHandling)
{
@ -1015,6 +940,14 @@ LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask)
handled_view = viewp;
break;
}
if (viewp->blockMouseEvent(local_x, local_y))
{
LLUI::sWindow->setCursor(viewp->getHoverCursor());
handled_view = viewp;
break;
}
}
}
return handled_view;
@ -1080,10 +1013,14 @@ LLView* LLView::childrenHandleMouseDown(S32 x, S32 y, MASK mask)
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleMouseDown( local_x, local_y, mask ))
if (!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled())
{
continue;
}
if(viewp->handleMouseDown( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
@ -1092,6 +1029,12 @@ LLView* LLView::childrenHandleMouseDown(S32 x, S32 y, MASK mask)
handled_view = viewp;
break;
}
if(viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
return handled_view;
}
@ -1107,10 +1050,15 @@ LLView* LLView::childrenHandleRightMouseDown(S32 x, S32 y, MASK mask)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleRightMouseDown( local_x, local_y, mask ))
if (!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled())
{
continue;
}
if (viewp->handleRightMouseDown( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
@ -1120,6 +1068,12 @@ LLView* LLView::childrenHandleRightMouseDown(S32 x, S32 y, MASK mask)
handled_view = viewp;
break;
}
if (viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
}
return handled_view;
@ -1136,10 +1090,14 @@ LLView* LLView::childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleMiddleMouseDown( local_x, local_y, mask ))
if (!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled())
{
continue;
}
if(viewp->handleMiddleMouseDown( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
@ -1148,6 +1106,12 @@ LLView* LLView::childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask)
handled_view = viewp;
break;
}
if (viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
}
return handled_view;
@ -1164,10 +1128,15 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleDoubleClick( local_x, local_y, mask ))
if (!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled())
{
continue;
}
if (viewp->handleDoubleClick( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
@ -1176,6 +1145,12 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask)
handled_view = viewp;
break;
}
if (viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
}
return handled_view;
@ -1191,12 +1166,13 @@ LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (!viewp->pointInView(local_x, local_y))
continue;
if (!viewp->getVisible())
continue;
if (!viewp->getEnabled())
if (!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled())
{
continue;
}
if (viewp->handleMouseUp( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
@ -1206,6 +1182,12 @@ LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask)
handled_view = viewp;
break;
}
if (viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
}
return handled_view;
@ -1221,10 +1203,14 @@ LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleRightMouseUp( local_x, local_y, mask ))
if (!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled() )
{
continue;
}
if(viewp->handleRightMouseUp( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
@ -1233,6 +1219,12 @@ LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)
handled_view = viewp;
break;
}
if(viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
}
return handled_view;
@ -1248,10 +1240,14 @@ LLView* LLView::childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask)
LLView* viewp = *child_it;
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleMiddleMouseUp( local_x, local_y, mask ))
if (!viewp->pointInView(local_x, local_y)
|| !viewp->getVisible()
|| !viewp->getEnabled())
{
continue;
}
if(viewp->handleMiddleMouseUp( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
@ -1260,6 +1256,12 @@ LLView* LLView::childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask)
handled_view = viewp;
break;
}
if (viewp->blockMouseEvent(local_x, local_y))
{
handled_view = viewp;
break;
}
}
}
return handled_view;
@ -1272,18 +1274,6 @@ void LLView::draw()
void LLView::drawChildren()
{
if (sDebugRects)
{
drawDebugRect();
// Check for bogus rectangle
if (getRect().mRight <= getRect().mLeft
|| getRect().mTop <= getRect().mBottom)
{
llwarns << "Bogus rectangle for " << getName() << " with " << mRect << llendl;
}
}
if (!mChildList.empty())
{
LLRect rootRect = getRootView()->getRect();
@ -1307,6 +1297,17 @@ void LLView::drawChildren()
{
LLUI::translate((F32)viewp->getRect().mLeft, (F32)viewp->getRect().mBottom, 0.f);
viewp->draw();
if (sDebugRects)
{
viewp->drawDebugRect();
// Check for bogus rectangle
if (!getRect().isValid())
{
llwarns << "Bogus rectangle for " << getName() << " with " << mRect << llendl;
}
}
}
LLUI::popMatrix();
}
@ -1353,10 +1354,6 @@ void LLView::drawDebugRect()
// draw red rectangle for the border
LLColor4 border_color(0.f, 0.f, 0.f, 1.f);
//if (sEditingUI)
//{
// border_color.mV[0] = 1.f;
//}
if(preview_iter != sPreviewHighlightedElements.end())
{
if(LLView::sPreviewClickedElement && this == sPreviewClickedElement)

View File

@ -42,8 +42,6 @@
#include "llfontgl.h"
#include "llmortician.h"
#include "llmousehandler.h"
#include "llnametable.h"
#include "llsd.h"
#include "llstring.h"
#include "llrect.h"
#include "llui.h"
@ -58,6 +56,8 @@
#include <list>
class LLSD;
const U32 FOLLOWS_NONE = 0x00;
const U32 FOLLOWS_LEFT = 0x01;
const U32 FOLLOWS_RIGHT = 0x02;
@ -124,21 +124,16 @@ public:
Optional<bool> enabled,
visible,
mouse_opaque,
use_bounding_rect;
use_bounding_rect,
from_xui;
Optional<S32> tab_group,
default_tab_group;
Optional<std::string> tool_tip;
Optional<S32> sound_flags;
Optional<bool> from_xui;
Optional<Follows> follows;
Optional<std::string> hover_cursor;
// font params
Optional<const LLFontGL*> font;
Optional<LLFontGL::HAlign> font_halign;
Optional<LLFontGL::VAlign> font_valign;
Optional<std::string> layout;
Optional<LLRect> rect;
@ -223,9 +218,6 @@ public:
virtual ~LLView();
// Hack to support LLFocusMgr (from LLMouseHandler)
/*virtual*/ BOOL isView() const;
// Some UI widgets need to be added as controls. Others need to
// be added as regular view children. isCtrl should return TRUE
// if a widget needs to be added as a ctrl
@ -258,6 +250,8 @@ public:
void setUseBoundingRect( BOOL use_bounding_rect );
BOOL getUseBoundingRect();
ECursorType getHoverCursor() { return mHoverCursor; }
const std::string& getToolTip() const { return mToolTipMsg.getString(); }
void sendChildToFront(LLView* child);
@ -443,12 +437,11 @@ public:
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect); // Display mToolTipMsg if no child handles it.
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
/*virtual*/ const std::string& getName() const;
/*virtual*/ std::string getName() const;
/*virtual*/ void onMouseCaptureLost();
/*virtual*/ BOOL hasMouseCapture();
/*virtual*/ BOOL isView(); // Hack to support LLFocusMgr
/*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const;
/*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
@ -545,7 +538,7 @@ protected:
LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks);
LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
LLView* childrenHandleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
LLView* childrenHandleToolTip(S32 x, S32 y, MASK mask);
ECursorType mHoverCursor;

View File

@ -24,9 +24,17 @@
#include "../llurlentry.h"
#include "llurlentry_stub.cpp"
#include "lltut.h"
#include "../lluicolortable.h"
#include <boost/regex.hpp>
LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& default_color) const
{
return LLUIColor();
}
LLUIColor::LLUIColor() {}
namespace tut
{
struct LLUrlEntryData
@ -276,6 +284,11 @@ namespace tut
testRegex("Agent Url multicase", r,
"XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX",
"secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About");
testRegex("Agent Url alternate command", r,
"XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",
"secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar");
}
template<> template<>

View File

@ -23,6 +23,10 @@
#include "../llurlmatch.h"
#include "lltut.h"
// link seam
LLUIColor::LLUIColor()
{}
namespace tut
{
struct LLUrlMatchData
@ -49,7 +53,7 @@ namespace tut
LLUrlMatch match;
ensure("empty()", match.empty());
match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", "", "");
match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", "");
ensure("! empty()", ! match.empty());
}
@ -62,7 +66,7 @@ namespace tut
LLUrlMatch match;
ensure_equals("getStart() == 0", match.getStart(), 0);
match.setValues(10, 20, "", "", "", "", "", "");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "");
ensure_equals("getStart() == 10", match.getStart(), 10);
}
@ -75,7 +79,7 @@ namespace tut
LLUrlMatch match;
ensure_equals("getEnd() == 0", match.getEnd(), 0);
match.setValues(10, 20, "", "", "", "", "", "");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "");
ensure_equals("getEnd() == 20", match.getEnd(), 20);
}
@ -88,10 +92,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getUrl() == ''", match.getUrl(), "");
match.setValues(10, 20, "http://slurl.com/", "", "", "", "", "");
match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", "");
ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/");
match.setValues(10, 20, "", "", "", "", "", "");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "");
ensure_equals("getUrl() == '' (2)", match.getUrl(), "");
}
@ -104,10 +108,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getLabel() == ''", match.getLabel(), "");
match.setValues(10, 20, "", "Label", "", "", "", "");
match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", "");
ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label");
match.setValues(10, 20, "", "", "", "", "", "");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "");
ensure_equals("getLabel() == '' (2)", match.getLabel(), "");
}
@ -120,10 +124,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getTooltip() == ''", match.getTooltip(), "");
match.setValues(10, 20, "", "", "Info", "", "", "");
match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", "");
ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info");
match.setValues(10, 20, "", "", "", "", "", "");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "");
ensure_equals("getTooltip() == '' (2)", match.getTooltip(), "");
}
@ -136,10 +140,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getIcon() == ''", match.getIcon(), "");
match.setValues(10, 20, "", "", "", "Icon", "", "");
match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", "");
ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon");
match.setValues(10, 20, "", "", "", "", "", "");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "");
ensure_equals("getIcon() == '' (2)", match.getIcon(), "");
}
@ -152,10 +156,10 @@ namespace tut
LLUrlMatch match;
ensure("getMenuName() empty", match.getMenuName().empty());
match.setValues(10, 20, "", "", "", "Icon", "xui_file.xml", "");
match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "");
ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml");
match.setValues(10, 20, "", "", "", "", "", "");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "");
ensure("getMenuName() empty (2)", match.getMenuName().empty());
}
@ -168,10 +172,10 @@ namespace tut
LLUrlMatch match;
ensure("getLocation() empty", match.getLocation().empty());
match.setValues(10, 20, "", "", "", "Icon", "xui_file.xml", "Paris");
match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris");
ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris");
match.setValues(10, 20, "", "", "", "", "", "");
match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "");
ensure("getLocation() empty (2)", match.getLocation().empty());
}
}

View File

@ -70,14 +70,11 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0;
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0;
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen) = 0;
virtual const std::string& getName() const = 0;
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask) = 0;
virtual std::string getName() const = 0;
virtual void onMouseCaptureLost() = 0;
// Hack to support LLFocusMgr
virtual BOOL isView() const = 0;
virtual void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const = 0;
virtual void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const = 0;

View File

@ -94,7 +94,7 @@ public:
// Get the contents of this preeditor as a LLWString. If there is an active preedit,
// the returned LLWString contains it.
virtual LLWString getWText() const = 0;
virtual LLWString getPreeditString() const = 0;
// Handle a UTF-32 char on this preeditor, i.e., add the character
// to the contents.

View File

@ -2016,7 +2016,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
// Although the spec. is unclear, replace range should
// not present when there is an active preedit. We just
// ignore the case. markAsPreedit will detect the case and warn it.
const LLWString & text = mPreeditor->getWText();
const LLWString & text = mPreeditor->getPreeditString();
const S32 location = wstring_wstring_length_from_utf16_length(text, 0, range.location);
const S32 length = wstring_wstring_length_from_utf16_length(text, location, range.length);
mPreeditor->markAsPreedit(location, length);
@ -2214,7 +2214,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
{
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
const LLWString & text = mPreeditor->getWText();
const LLWString & text = mPreeditor->getPreeditString();
LLCoordGL caret_coord;
LLRect preedit_bounds;
@ -2251,7 +2251,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
mPreeditor->getSelectionRange(&selection, &selection_length);
if (selection_length)
{
const LLWString text = mPreeditor->getWText().substr(selection, selection_length);
const LLWString text = mPreeditor->getPreeditString().substr(selection, selection_length);
const llutf16string text_utf16 = wstring_to_utf16str(text);
result = SetEventParameter(event, kEventParamTextInputReplyText, typeUnicodeText,
text_utf16.length() * sizeof(U16), text_utf16.c_str());
@ -2637,7 +2637,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
const LLWString & text = mPreeditor->getWText();
const LLWString & text = mPreeditor->getPreeditString();
const CFIndex length = wstring_utf16_length(text, 0, preedit)
+ wstring_utf16_length(text, preedit + preedit_length, text.length());
result = SetEventParameter(event, kEventParamTSMDocAccessCharacterCount, typeCFIndex, sizeof(length), &length);
@ -2654,7 +2654,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
const LLWString & text = mPreeditor->getWText();
const LLWString & text = mPreeditor->getPreeditString();
CFRange range;
if (preedit_length)
@ -2688,7 +2688,7 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e
{
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
const LLWString & text = mPreeditor->getWText();
const LLWString & text = mPreeditor->getPreeditString();
// The GetCharacters event of TSMDA has a fundamental flaw;
// An input method need to decide the starting offset and length

View File

@ -3544,7 +3544,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
// WCHARs, i.e., UTF-16 encoding units, so we can't simply pass the
// number to getPreeditLocation.
const LLWString & wtext = mPreeditor->getWText();
const LLWString & wtext = mPreeditor->getPreeditString();
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);
LLCoordGL caret_coord;
@ -3571,7 +3571,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
case IMR_RECONVERTSTRING:
{
mPreeditor->resetPreedit();
const LLWString & wtext = mPreeditor->getWText();
const LLWString & wtext = mPreeditor->getPreeditString();
S32 select, select_length;
mPreeditor->getSelectionRange(&select, &select_length);
@ -3613,7 +3613,7 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
}
case IMR_DOCUMENTFEED:
{
const LLWString & wtext = mPreeditor->getWText();
const LLWString & wtext = mPreeditor->getPreeditString();
S32 preedit, preedit_length;
mPreeditor->getPreeditRange(&preedit, &preedit_length);

View File

@ -34,7 +34,7 @@
#define LL_LLXMLNODE_H
#ifndef XML_STATIC
#define XML_STATIC 1
#define XML_STATIC
#endif
#ifdef LL_STANDALONE
#include <expat.h>

View File

@ -34,7 +34,7 @@
#define LL_LLXMLPARSER_H
#ifndef XML_STATIC
#define XML_STATIC 1
#define XML_STATIC
#endif
#ifdef LL_STANDALONE
#include <expat.h>

View File

@ -1568,11 +1568,11 @@ namespace LLInitParam
public Param
{
public:
typedef BlockValue<T> self_t;
typedef Block<TypedParam<T, TypeValues<T>, false> > block_t;
typedef const T& value_const_ref_t;
typedef value_const_ref_t value_assignment_t;
typedef typename TypeValues<T>::KeyCache key_cache_t;
typedef BlockValue<T> self_t;
typedef Block<TypedParam<T, TypeValues<T>, false> > block_t;
typedef const T& value_const_ref_t;
typedef value_const_ref_t value_assignment_t;
typedef typename TypeValues<T>::KeyCache key_cache_t;
BlockValue(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr),
@ -1754,11 +1754,16 @@ namespace LLInitParam
protected:
value_assignment_t get() const
{
if (mData.mLastParamVersion < BaseBlock::getLastChangeVersion() && block_t::validateBlock(true))
// if some parameters were provided, issue warnings on invalid blocks
if (Param::getProvided() && (mData.mLastParamVersion < BaseBlock::getLastChangeVersion()))
{
mData.mValue = static_cast<const DERIVED*>(this)->getValueFromBlock();
mData.clearKey();
mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
// go ahead and issue warnings at this point if any param is invalid
if(block_t::validateBlock(false))
{
mData.mValue = static_cast<const DERIVED*>(this)->getValueFromBlock();
mData.clearKey();
mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
}
}
return mData.mValue;

View File

@ -194,3 +194,68 @@ bool LLTrans::findString(std::string &result, const std::string &xml_desc, const
return false;
}
}
//static
std::string LLTrans::getCountString(const std::string& language, const std::string& xml_desc, S32 count)
{
// Compute which string identifier to use
const char* form = "";
if (language == "ru") // Russian
{
// From GNU ngettext()
// Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
if (count % 10 == 1
&& count % 100 != 11)
{
// singular, "1 item"
form = "A";
}
else if (count % 10 >= 2
&& count % 10 <= 4
&& (count % 100 < 10 || count % 100 >= 20) )
{
// special case "2 items", "23 items", but not "13 items"
form = "B";
}
else
{
// English-style plural, "5 items"
form = "C";
}
}
else if (language == "fr" || language == "pt") // French, Brazilian Portuguese
{
// French and Portuguese treat zero as a singular "0 item" not "0 items"
if (count == 0 || count == 1)
{
form = "A";
}
else
{
// English-style plural
form = "B";
}
}
else // default
{
// languages like English with 2 forms, singular and plural
if (count == 1)
{
// "1 item"
form = "A";
}
else
{
// "2 items", also use plural for "0 items"
form = "B";
}
}
// Translate that string
LLStringUtil::format_map_t args;
args["[COUNT]"] = llformat("%d", count);
// Look up "AgeYearsB" or "AgeWeeksC" including the "form"
std::string key = llformat("%s%s", xml_desc.c_str(), form);
return getString(key, args);
}

View File

@ -80,6 +80,12 @@ public:
static std::string getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args);
static bool findString(std::string &result, const std::string &xml_desc, const LLStringUtil::format_map_t& args);
// Returns translated string with [COUNT] replaced with a number, following
// special per-language logic for plural nouns. For example, some languages
// may have different plurals for 0, 1, 2 and > 2.
// See "AgeWeeksA", "AgeWeeksB", etc. in strings.xml for examples.
static std::string getCountString(const std::string& language, const std::string& xml_desc, S32 count);
/**
* @brief Returns a translated string
* @param xml_desc String's description

View File

@ -106,6 +106,7 @@ set(viewer_SOURCE_FILES
llconfirmationmanager.cpp
llcurrencyuimanager.cpp
llcylinder.cpp
lldateutil.cpp
lldebugmessagebox.cpp
lldebugview.cpp
lldelayedgestureerror.cpp
@ -241,6 +242,7 @@ set(viewer_SOURCE_FILES
llimview.cpp
llimcontrolpanel.cpp
llinspectavatar.cpp
llinspectobject.cpp
llinventorybridge.cpp
llinventoryclipboard.cpp
llinventoryfilter.cpp
@ -395,7 +397,6 @@ set(viewer_SOURCE_FILES
lltoastimpanel.cpp
lltoastnotifypanel.cpp
lltoastpanel.cpp
lltoggleablemenu.cpp
lltoolbar.cpp
lltoolbrush.cpp
lltoolcomp.cpp
@ -576,6 +577,7 @@ set(viewer_HEADER_FILES
llconfirmationmanager.h
llcurrencyuimanager.h
llcylinder.h
lldateutil.h
lldebugmessagebox.h
lldebugview.h
lldelayedgestureerror.h
@ -711,6 +713,7 @@ set(viewer_HEADER_FILES
llimview.h
llimcontrolpanel.h
llinspectavatar.h
llinspectobject.h
llinventorybridge.h
llinventoryclipboard.h
llinventoryfilter.h
@ -865,7 +868,6 @@ set(viewer_HEADER_FILES
lltoastimpanel.h
lltoastnotifypanel.h
lltoastpanel.h
lltoggleablemenu.h
lltool.h
lltoolbar.h
lltoolbrush.h
@ -1538,9 +1540,12 @@ if (INSTALL)
include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
endif (INSTALL)
# To add a viewer unit test, just add the test .cpp file below
# This creates a separate test project per file listed.
include(LLAddBuildTest)
SET(viewer_TEST_SOURCE_FILES
llagentaccess.cpp
lldateutil.cpp
llviewerhelputil.cpp
)
set_source_files_properties(

View File

@ -3673,7 +3673,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<string>0.1</string>
<real>0.15</real>
</map>
<key>InstallLanguage</key>
<map>
@ -7585,7 +7585,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<integer>0</integer>
</map>
<key>ShowCameraButton</key>
<map>
@ -8456,18 +8456,40 @@
<key>Value</key>
<real>0.2</real>
</map>
<key>ToolTipVisibleTime</key>
<map>
<key>Comment</key>
<string>Fade tooltip after mouse is idle for this long</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>10.0</real>
</map>
<key>ToolboxAutoMove</key>
<key>ToolTipVisibleTimeFar</key>
<map>
<key>Comment</key>
<string>Fade tooltip after after time passes (seconds) while mouse not near tooltip</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>ToolTipVisibleTimeNear</key>
<map>
<key>Comment</key>
<string>Fade tooltip after after time passes (seconds) while mouse near tooltip</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>5.0</real>
</map>
<key>ToolTipVisibleTimeOver</key>
<map>
<key>Comment</key>
<string>Fade tooltip after after time passes (seconds) while mouse over tooltip</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1000.0</real>
</map>
<key>ToolboxAutoMove</key>
<map>
<key>Comment</key>
<string>[NOT USED]</string>
@ -9654,39 +9676,6 @@
<string>S32</string>
<key>Value</key>
<integer>15</integer>
</map>
<key>UITextEditorBorder</key>
<map>
<key>Comment</key>
<string>UI Text Editor Border</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>UITextEditorHPad</key>
<map>
<key>Comment</key>
<string>UI Text Horizontal Pad</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>UITextEditorVPadTop</key>
<map>
<key>Comment</key>
<string>UI Text Vertical Pad Top</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>UploadBakedTexOld</key>
<map>

View File

@ -758,7 +758,7 @@ CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \
"InternetShortcut" "URL" \
"http://www.secondlife.com/registration/"
"http://join.secondlife.com/"
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Your Account.url" \
"InternetShortcut" "URL" \
"http://www.secondlife.com/account/"

View File

@ -696,9 +696,6 @@ bool LLAppViewer::init()
// Let code in llui access the viewer help floater
LLUI::sHelpImpl = LLViewerHelp::getInstance();
// Set the link color for any Urls in text fields
LLTextBase::setLinkColor( LLUIColorTable::instance().getColor("HTMLLinkColor") );
// Load translations for tooltips
LLFloater::initClass();
@ -1424,6 +1421,9 @@ bool LLAppViewer::cleanup()
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
}
// Turn off Space Navigator and similar devices
LLViewerJoystick::getInstance()->terminate();
removeMarkerFile(); // Any crashes from here on we'll just have to ignore
writeDebugInfo();
@ -2379,7 +2379,6 @@ void LLAppViewer::cleanupSavedSettings()
}
gSavedSettings.setF32("MapScale", gMapScale );
gSavedSettings.setBOOL("ShowHoverTips", gToolTipView->getVisible());
// Some things are cached in LLAgent.
if (gAgent.mInitialized)

View File

@ -39,16 +39,22 @@
#include "lldarray.h"
#include "llnotifications.h"
#include "roles_constants.h" // for GP_MEMBER_INVITE
#include "llagent.h"
#include "llappviewer.h" // for gLastVersionChannel
#include "llcachename.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llgivemoney.h" // foe LLFloaterPay
#include "llfloatergroupinvite.h"
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llgivemoney.h"
#include "llinventorymodel.h" // for gInventory.findCategoryUUIDForType
#include "llimview.h" // for gIMMgr
#include "llmutelist.h"
#include "llrecentpeople.h"
#include "llsidetray.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
#include "llviewerregion.h"
@ -244,6 +250,17 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
}
}
void LLAvatarActions::inviteToGroup(const LLUUID& id)
{
LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(id));
if (widget)
{
widget->center();
widget->setPowersMask(GP_MEMBER_INVITE);
widget->setSelectGroupCallback(boost::bind(callback_invite_to_group, _1, id));
}
}
//== private methods ========================================================================================
// static
@ -293,6 +310,16 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response,
return false;
}
// static
void LLAvatarActions::callback_invite_to_group(LLUUID group_id, LLUUID id)
{
std::vector<LLUUID> agent_ids;
agent_ids.push_back(id);
LLFloaterGroupInvite::showForGroup(group_id, &agent_ids);
}
// static
bool LLAvatarActions::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response)
{

View File

@ -96,11 +96,17 @@ public:
*/
static bool isBlocked(const LLUUID& id);
/**
* Invite avatar to a group.
*/
static void inviteToGroup(const LLUUID& id);
private:
static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
static bool handleRemove(const LLSD& notification, const LLSD& response);
static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id);
static void callback_invite_to_group(LLUUID group_id, LLUUID id);
// Just request friendship, no dialog.
static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message);

View File

@ -148,7 +148,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id)
void LLAvatarListItem::onInfoBtnClick()
{
LLFloaterReg::showInstance("inspect_avatar", mAvatarId);
LLFloaterReg::showInstance("inspect_avatar", LLSD().insert("avatar_id", mAvatarId));
/* TODO fix positioning of inspector
localPointToScreen(mXPos, mYPos, &mXPos, &mYPos);

View File

@ -42,12 +42,18 @@
#include "llavatarconstants.h" // AVATAR_TRANSACTED, etc.
#include "lldate.h"
#include "lltrans.h"
#include "llui.h" // LLUI::getLanguage()
#include "message.h"
LLAvatarPropertiesProcessor::LLAvatarPropertiesProcessor()
{
}
LLAvatarPropertiesProcessor::~LLAvatarPropertiesProcessor()
{
llinfos << "JAMESDEBUG cleanup avatar properties processor" << llendl;
}
void LLAvatarPropertiesProcessor::addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
{
// Check if that observer is already in mObservers for that avatar_id
@ -172,103 +178,6 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData*
gAgent.sendReliableMessage();
}
//static
std::string LLAvatarPropertiesProcessor::ageFromDate(const std::string& date_string)
{
// Convert string date to malleable representation
S32 month, day, year;
S32 matched = sscanf(date_string.c_str(), "%d/%d/%d", &month, &day, &year);
if (matched != 3) return "???";
// Create ISO-8601 date string
std::string iso8601_date_string =
llformat("%04d-%02d-%02dT00:00:00Z", year, month, day);
LLDate date(iso8601_date_string);
// Correct for the fact that account creation dates are in Pacific time,
// == UTC - 8
F64 date_secs_since_epoch = date.secondsSinceEpoch();
date_secs_since_epoch += 8.0 * 60.0 * 60.0;
// Convert seconds from epoch to seconds from now
F64 now_secs_since_epoch = LLDate::now().secondsSinceEpoch();
F64 age_secs = now_secs_since_epoch - date_secs_since_epoch;
// We don't care about sub-day times
const F64 SEC_PER_DAY = 24.0 * 60.0 * 60.0;
S32 age_days = lltrunc(age_secs / SEC_PER_DAY);
// Assume most values won't be used to fill in the format string:
// "[AGEYEARS][AGEMONTHS][AGEWEEKS][AGEDAYS]old"
LLStringUtil::format_map_t final_args;
final_args["[AGEYEARS]"] = "";
final_args["[AGEMONTHS]"] = "";
final_args["[AGEWEEKS]"] = "";
final_args["[AGEDAYS]"] = "";
// Try for age in round number of years
LLStringUtil::format_map_t args;
S32 age_years = age_days / 365;
age_days = age_days % 365;
if (age_years > 1)
{
args["[YEARS]"] = llformat("%d", age_years);
final_args["[AGEYEARS]"] = LLTrans::getString("AgeYears", args);
}
else if (age_years == 1)
{
final_args["[AGEYEARS]"] = LLTrans::getString("Age1Year");
}
// fall through because we show years + months for ages > 1 year
S32 age_months = age_days / 30;
age_days = age_days % 30;
if (age_months > 1)
{
args["[MONTHS]"] = llformat("%d", age_months);
final_args["[AGEMONTHS]"] = LLTrans::getString("AgeMonths", args);
// Either N years M months, or just M months,
// so we can exit.
return LLTrans::getString("YearsMonthsOld", final_args);
}
else if (age_months == 1)
{
final_args["[AGEMONTHS]"] = LLTrans::getString("Age1Month");
return LLTrans::getString("YearsMonthsOld", final_args);
}
// Now for age in weeks
S32 age_weeks = age_days / 7;
age_days = age_days % 7;
if (age_weeks > 1)
{
args["[WEEKS]"] = llformat("%d", age_weeks);
final_args["[AGEWEEKS]"] = LLTrans::getString("AgeWeeks", args);
return LLTrans::getString("WeeksOld", final_args);
}
else if (age_weeks == 1)
{
final_args["[AGEWEEKS]"] = LLTrans::getString("Age1Week");
return LLTrans::getString("WeeksOld", final_args);
}
// Down to days now
if (age_days > 1)
{
args["[DAYS]"] = llformat("%d", age_days);
final_args["[AGEDAYS]"] = LLTrans::getString("AgeDays", args);
return LLTrans::getString("DaysOld", final_args);
}
else if (age_days == 1)
{
final_args["[AGEDAYS]"] = LLTrans::getString("Age1Day");
return LLTrans::getString("DaysOld", final_args);
}
else
{
return LLTrans::getString("TodayOld");
}
}
//static

View File

@ -36,6 +36,7 @@
#include "lluuid.h"
#include "llsingleton.h"
#include "v3dmath.h" // LLVector3d
#include <list>
#include <map>
/*
@ -147,8 +148,7 @@ class LLAvatarPropertiesProcessor
public:
LLAvatarPropertiesProcessor();
virtual ~LLAvatarPropertiesProcessor()
{}
virtual ~LLAvatarPropertiesProcessor();
void addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer);
@ -174,11 +174,6 @@ public:
void sendPickDelete(const LLUUID& pick_id);
// Convert a date provided by the server (MM/DD/YYYY) into a localized,
// human-readable age (1 year, 2 months) using translation strings from
// the XML file.
static std::string ageFromDate(const std::string& date_string);
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
static std::string accountType(const LLAvatarData* avatar_data);

View File

@ -236,7 +236,7 @@ BOOL LLNearbyChatToastPanel::handleMouseDown (S32 x, S32 y, MASK mask)
S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
if(msg_inspector->pointInView(local_x, local_y))
{
LLFloaterReg::showInstance("inspect_avatar", mFromID);
LLFloaterReg::showInstance("inspect_avatar", LLSD().insert("avatar_id", mFromID));
}
else
{
@ -262,7 +262,7 @@ bool LLNearbyChatToastPanel::canAddText ()
LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
if(!msg_text)
return false;
return msg_text->getTextLinesNum()<10;
return msg_text->getLineCount()<10;
}
BOOL LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)

View File

@ -39,10 +39,44 @@
static LLDefaultChildRegistry::Register<LLChatMsgBox> r("text_chat");
class ChatSeparator : public LLTextSegment
{
public:
ChatSeparator(S32 start, S32 end)
: LLTextSegment(start, end),
mEditor(NULL)
{}
/*virtual*/ void linkToDocument(class LLTextBase* editor)
{
mEditor = editor;
}
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor)
{
mEditor = NULL;
}
/*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const
{
return mEditor->getDocumentPanel()->getRect().getWidth();
}
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
{
gl_line_2d(draw_rect.mLeft + 5, draw_rect.getCenterY(), draw_rect.mRight - 5, draw_rect.getCenterY(), LLColor4::grey);
return draw_rect.getWidth();
}
private:
LLTextBase* mEditor;
};
LLChatMsgBox::Params::Params() :
block_spacing("block_spacing", 10)
{
line_spacing = 4;
line_spacing.pixels = 4;
}
LLChatMsgBox::LLChatMsgBox(const Params& p) :
@ -52,75 +86,13 @@ LLChatMsgBox::LLChatMsgBox(const Params& p) :
void LLChatMsgBox::addText( const LLStringExplicit& text )
{
LLWString t = mText.getWString();
if (! t.empty())
S32 length = getLength();
// if there is existing text, add a separator
if (length > 0)
{
t += '\n';
}
t += getWrappedText(text);
LLTextBox::setText(wstring_to_utf8str(t));
mSeparatorOffset.push_back(getLength());
}
void LLChatMsgBox::setText(const LLStringExplicit& text)
{
mSeparatorOffset.clear();
mText.clear();
addText(text);
}
void LLChatMsgBox::setValue(const LLSD& value )
{
setText(value.asString());
}
S32 LLChatMsgBox::getTextPixelHeight()
{
S32 num_blocks = mSeparatorOffset.size();
S32 num_lines = getTextLinesNum();
return (S32)(num_lines * mDefaultFont->getLineHeight() + \
(num_lines-1) * mLineSpacing + \
(num_blocks-1) * mBlockSpacing + \
2 * mLineSpacing);
}
S32 LLChatMsgBox::getTextLinesNum()
{
S32 num_lines = getLineCount();
if (num_lines < 1)
{
num_lines = 1;
}
return num_lines;
}
void LLChatMsgBox::drawText(S32 x, S32 y, const LLWString &text, const LLColor4 &color)
{
S32 start = 0;
S32 width = getRect().getWidth()-10;
// iterate through each block of text that has been added
y -= mLineSpacing;
for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); it != mSeparatorOffset.end() ;)
{
// display the text for this block
S32 num_chars = *it - start;
LLWString text = mDisplayText.substr(start, num_chars);
LLTextBox::drawText(x, y, text, color);
// exit the loop if this is the last text block
start += num_chars + 1; // skip the newline
if (++it == mSeparatorOffset.end())
{
break;
}
// output a separator line between blocks
S32 num_lines = std::count(text.begin(), text.end(), '\n') + 1;
y -= num_lines * (llfloor(mDefaultFont->getLineHeight()) + mLineSpacing);
S32 sep_y = y - mBlockSpacing/2 + mLineSpacing/2;
gl_line_2d(5, sep_y, width, sep_y, LLColor4::grey);
y -= mBlockSpacing;
// chat separator exists right before the null terminator
insertSegment(new ChatSeparator(length - 1, length - 1));
}
// prepend newline only if there is some existing text
appendText(text, length > 0);
}

View File

@ -61,18 +61,10 @@ protected:
friend class LLUICtrlFactory;
public:
void setText(const LLStringExplicit &text);
void addText(const LLStringExplicit &text);
S32 getTextPixelHeight();
S32 getTextLinesNum();
/*virtual*/ void setValue(const LLSD &value);
/*virtual*/ void drawText(S32 x, S32 y, const LLWString &text, const LLColor4 &color);
private:
S32 mBlockSpacing;
std::vector<S32> mSeparatorOffset;
};
#endif

View File

@ -1305,7 +1305,7 @@ void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
{
LLRect rc;
S32 text_width = getFont()->getWidth(getText());
S32 text_width = getContentsRect().getWidth();
rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth);

View File

@ -87,7 +87,7 @@ LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p)
tp.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
}
tp.text(p.label);
tp.initial_value(p.label());
mCaption = LLUICtrlFactory::create<LLTextBox>(tp);
addChild( mCaption );

Some files were not shown because too many files have changed in this diff Show More