Merge branch 'V2MultiWear' of git://github.com/Shyotl/SingularityViewer into V2MultiWear

Conflicts:
	indra/newview/llfloateravatarlist.cpp
	indra/newview/llfloatermessagelog.cpp
	indra/newview/llstartup.cpp
	indra/newview/llviewermenu.cpp
	indra/newview/llviewermessage.cpp
	indra/newview/skins/default/xui/fr/menu_inventory.xml
This commit is contained in:
Siana Gearz
2012-03-28 22:27:45 +02:00
264 changed files with 27606 additions and 15368 deletions

View File

@@ -5,22 +5,26 @@ project(llui)
include(00-Common)
include(LLCommon)
include(LLImage)
include(LLInventory)
include(LLMath)
include(LLMessage)
include(LLRender)
include(LLWindow)
include(LLVFS)
include(LLXML)
include(LLXUIXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLXUIXML_INCLUDE_DIRS}
)
set(llui_SOURCE_FILES
@@ -75,6 +79,7 @@ set(llui_SOURCE_FILES
lluistring.cpp
llundo.cpp
llviewborder.cpp
llviewmodel.cpp
llview.cpp
llviewquery.cpp
)
@@ -142,6 +147,7 @@ set(llui_HEADER_FILES
lluixmltags.h
llundo.h
llviewborder.h
llviewmodel.h
llview.h
llviewquery.h
)
@@ -159,6 +165,7 @@ target_link_libraries(llui
llwindow
llimage
llvfs # ugh, just for LLDir
llxuixml
llxml
llcommon # must be after llimage, llwindow, llrender
llmath

File diff suppressed because it is too large Load Diff

View File

@@ -41,6 +41,8 @@
#include "llfontgl.h"
#include "lluiimage.h"
#include "lluistring.h"
#include "llinitparam.h"
#include "lluicolor.h"
//
// Constants
@@ -85,21 +87,26 @@ public:
const LLFontGL* mGLFont = NULL,
const std::string& unselected_label = LLStringUtil::null,
const std::string& selected_label = LLStringUtil::null );
public:
virtual ~LLButton();
void init(void (*click_callback)(void*), void *callback_data, const LLFontGL* font, const std::string& control_name);
~LLButton();
// For backward compatability only
typedef boost::function<void(void*)> button_callback_t;
void addImageAttributeToXML(LLXMLNodePtr node, const std::string& imageName,
const LLUUID& imageID,const std::string& xmlTagName) const;
void addImageAttributeToXML(LLXMLNodePtr node, const LLPointer<LLUIImage>, const std::string& xmlTagName) const;
void init(void (*click_callback)(void*), void *callback_data, const std::string& control_name);
virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
virtual void setAlpha( F32 alpha ) { mAlpha = alpha; }
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual BOOL handleKeyHere(KEY key, MASK mask);
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 handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual void draw();
virtual void onMouseCaptureLost();
@@ -109,29 +116,48 @@ public:
void setUnselectedLabelColor( const LLColor4& c ) { mUnselectedLabelColor = c; }
void setSelectedLabelColor( const LLColor4& c ) { mSelectedLabelColor = c; }
void setClickedCallback( void (*cb)(void *data), void* data = NULL ); // mouse down and up within button
void setMouseDownCallback( void (*cb)(void *data) ) { mMouseDownCallback = cb; } // mouse down within button
void setMouseUpCallback( void (*cb)(void *data) ) { mMouseUpCallback = cb; } // mouse up, EVEN IF NOT IN BUTTON
void setHeldDownCallback( void (*cb)(void *data) ) { mHeldDownCallback = cb; } // Mouse button held down and in button
/*boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb);
boost::signals2::connection setMouseDownCallback(const CommitCallbackParam& cb);
boost::signals2::connection setMouseUpCallback(const CommitCallbackParam& cb);
boost::signals2::connection setHeldDownCallback(const CommitCallbackParam& cb);*/
boost::signals2::connection setClickedCallback( const commit_signal_t::slot_type& cb ); // mouse down and up within button
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ); // mouse up, EVEN IF NOT IN BUTTON
// Passes a 'count' parameter in the commit param payload, i.e. param["count"])
boost::signals2::connection setHeldDownCallback( const commit_signal_t::slot_type& cb ); // Mouse button held down and in button
// *TODO: Deprecate (for backwards compatability only)
boost::signals2::connection setClickedCallback( button_callback_t cb, void* data );
boost::signals2::connection setMouseDownCallback( button_callback_t cb, void* data );
boost::signals2::connection setMouseUpCallback( button_callback_t cb, void* data );
boost::signals2::connection setHeldDownCallback( button_callback_t cb, void* data );
void setHeldDownDelay( F32 seconds, S32 frames = 0) { mHeldDownDelay = seconds; mHeldDownFrameDelay = frames; }
F32 getHeldDownTime() const { return mMouseDownTimer.getElapsedTimeF32(); }
BOOL getIsToggle() const { return mIsToggle; }
void setIsToggle(BOOL is_toggle) { mIsToggle = is_toggle; }
BOOL toggleState();
BOOL getToggleState() const { return mToggleState; }
BOOL getToggleState() const;
void setToggleState(BOOL b);
void setHighlight(bool b);
void setFlashing( BOOL b );
BOOL getFlashing() const { return mFlashing; }
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
LLFontGL::HAlign getHAlign() const { return mHAlign; }
void setLeftHPad( S32 pad ) { mLeftHPad = pad; }
S32 getLeftHPad() const { return mLeftHPad; }
S32 getLeftHPad() const { return mLeftHPad; }
void setRightHPad( S32 pad ) { mRightHPad = pad; }
S32 getRightHPad() const { return mRightHPad; }
S32 getRightHPad() const { return mRightHPad; }
void setImageOverlayTopPad( S32 pad ) { mImageOverlayTopPad = pad; }
S32 getImageOverlayTopPad() const { return mImageOverlayTopPad; }
void setImageOverlayBottomPad( S32 pad ) { mImageOverlayBottomPad = pad; }
S32 getImageOverlayBottomPad() const { return mImageOverlayBottomPad; }
const std::string getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); }
const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); }
@@ -139,35 +165,31 @@ public:
void setImageColor(const std::string& color_control);
void setImageColor(const LLColor4& c);
/*virtual*/ void setColor(const LLColor4& c);
/*virtual*/ void setAlpha(F32 alpha);
void setImages(const std::string &image_name, const std::string &selected_name);
void setDisabledImages(const std::string &image_name, const std::string &selected_name);
void setDisabledImages(const std::string &image_name, const std::string &selected_name, const LLColor4& c);
void setHoverImages(const std::string &image_name, const std::string &selected_name);
void setDisabledImageColor(const LLColor4& c) { mDisabledImageColor = c; }
void setDisabledSelectedLabelColor( const LLColor4& c ) { mDisabledSelectedLabelColor = c; }
void setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
void setImageOverlay(const LLUUID& image_id, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white);
LLPointer<LLUIImage> getImageOverlay() { return mImageOverlay; }
LLFontGL::HAlign getImageOverlayHAlign() const { return mImageOverlayAlignment; }
virtual void setValue(const LLSD& value );
virtual LLSD getValue() const;
void autoResize(); // resize with label of current btn state
void resize(LLUIString label); // resize with label input
void setLabel( const LLStringExplicit& label);
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
void setLabelUnselected(const LLStringExplicit& label);
void setLabelSelected(const LLStringExplicit& label);
void setDisabledLabel(const LLStringExplicit& disabled_label);
void setDisabledSelectedLabel(const LLStringExplicit& disabled_label);
void setDisabledLabelColor( const LLColor4& c ) { mDisabledLabelColor = c; }
void setFont(const LLFontGL *font)
{ mGLFont = ( font ? font : LLFontGL::getFontSansSerif()); }
const LLFontGL* getFont() const { return mGLFont; }
const LLUIString& getCurrentLabel() const;
void setScaleImage(BOOL scale) { mScaleImage = scale; }
BOOL getScaleImage() const { return mScaleImage; }
@@ -175,132 +197,130 @@ public:
void setBorderEnabled(BOOL b) { mBorderEnabled = b; }
static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; }
void setImageUnselected(const std::string &image_name);
const std::string& getImageUnselectedName() const { return mImageUnselectedName; }
void setImageSelected(const std::string &image_name);
const std::string& getImageSelectedName() const { return mImageSelectedName; }
void setImageHoverSelected(const std::string &image_name);
void setImageHoverUnselected(const std::string &image_name);
void setImageDisabled(const std::string &image_name);
void setImageDisabledSelected(const std::string &image_name);
void setImageUnselected(LLPointer<LLUIImage> image);
void setImageSelected(LLPointer<LLUIImage> image);
void setImageHoverSelected(LLPointer<LLUIImage> image);
void setImageHoverUnselected(LLPointer<LLUIImage> image);
void setImageDisabled(LLPointer<LLUIImage> image);
void setImageDisabledSelected(LLPointer<LLUIImage> image);
void setImageFlash(LLPointer<LLUIImage> image);
void setImagePressed(LLPointer<LLUIImage> image);
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; }
static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
void setHelpURLCallback(const std::string &help_url);
const std::string& getHelpURL() const { return mHelpURL; }
void setForcePressedState(bool b) { mForcePressedState = b; }
void setAutoResize(bool auto_resize) { mAutoResize = auto_resize; }
bool getIsToggle() const { return mIsToggle; }
bool setIsToggle(bool toggle) { return mIsToggle = toggle; }
protected:
virtual void drawBorder(const LLColor4& color, S32 size);
void setImageUnselectedID(const LLUUID &image_id);
const LLUUID& getImageUnselectedID() const { return mImageUnselectedID; }
void setImageSelectedID(const LLUUID &image_id);
const LLUUID& getImageSelectedID() const { return mImageSelectedID; }
void setImageHoverSelectedID(const LLUUID &image_id);
void setImageHoverUnselectedID(const LLUUID &image_id);
void setImageDisabledID(const LLUUID &image_id);
void setImageDisabledSelectedID(const LLUUID &image_id);
const LLPointer<LLUIImage>& getImageUnselected() const { return mImageUnselected; }
const LLPointer<LLUIImage>& getImageSelected() const { return mImageSelected; }
void getOverlayImageSize(S32& overlay_width, S32& overlay_height);
LLFrameTimer mMouseDownTimer;
bool mNeedsHighlight;
S32 mButtonFlashCount;
F32 mButtonFlashRate;
private:
void (*mClickedCallback)(void* data );
void (*mMouseDownCallback)(void *data);
void (*mMouseUpCallback)(void *data);
void (*mHeldDownCallback)(void *data);
void drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size);
void resetMouseDownTimer();
commit_signal_t* mMouseDownSignal;
commit_signal_t* mMouseUpSignal;
commit_signal_t* mHeldDownSignal;
const LLFontGL *mGLFont;
S32 mMouseDownFrame;
F32 mHeldDownDelay; // seconds, after which held-down callbacks get called
S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called
S32 mMouseDownFrame;
S32 mMouseHeldDownCount; // Counter for parameter passed to held-down callback
F32 mHeldDownDelay; // seconds, after which held-down callbacks get called
S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called
LLPointer<LLUIImage> mImageOverlay;
LLFontGL::HAlign mImageOverlayAlignment;
LLColor4 mImageOverlayColor;
LLFontGL::HAlign mImageOverlayAlignment;
LLUIColor mImageOverlayColor;
LLUIColor mImageOverlaySelectedColor;
LLUIColor mImageOverlayDisabledColor;
LLPointer<LLUIImage> mImageUnselected;
LLUIString mUnselectedLabel;
LLColor4 mUnselectedLabelColor;
LLPointer<LLUIImage> mImageUnselected;
LLUIString mUnselectedLabel;
LLUIColor mUnselectedLabelColor;
LLPointer<LLUIImage> mImageSelected;
LLUIString mSelectedLabel;
LLColor4 mSelectedLabelColor;
LLPointer<LLUIImage> mImageSelected;
LLUIString mSelectedLabel;
LLUIColor mSelectedLabelColor;
LLPointer<LLUIImage> mImageHoverSelected;
LLPointer<LLUIImage> mImageHoverSelected;
LLPointer<LLUIImage> mImageHoverUnselected;
LLPointer<LLUIImage> mImageHoverUnselected;
LLPointer<LLUIImage> mImageDisabled;
LLUIString mDisabledLabel;
LLColor4 mDisabledLabelColor;
LLPointer<LLUIImage> mImageDisabled;
LLUIColor mDisabledLabelColor;
LLPointer<LLUIImage> mImageDisabledSelected;
LLUIString mDisabledSelectedLabel;
LLColor4 mDisabledSelectedLabelColor;
LLPointer<LLUIImage> mImageDisabledSelected;
LLUIString mDisabledSelectedLabel;
LLUIColor mDisabledSelectedLabelColor;
LLUUID mImageUnselectedID;
LLUUID mImageSelectedID;
LLUUID mImageHoverSelectedID;
LLUUID mImageHoverUnselectedID;
LLUUID mImageDisabledID;
LLUUID mImageDisabledSelectedID;
std::string mImageUnselectedName;
std::string mImageSelectedName;
std::string mImageHoverSelectedName;
std::string mImageHoverUnselectedName;
std::string mImageDisabledName;
std::string mImageDisabledSelectedName;
LLPointer<LLUIImage> mImagePressed;
LLPointer<LLUIImage> mImagePressedSelected;
LLColor4 mHighlightColor;
LLColor4 mUnselectedBgColor;
LLColor4 mSelectedBgColor;
LLColor4 mFlashBgColor;
/* There are two ways an image can flash- by making changes in color according to flash_color attribute
or by changing icon from current to the one specified in image_flash. Second way is used only if
flash icon name is set in attributes(by default it isn't). First way is used otherwise. */
LLPointer<LLUIImage> mImageFlash;
LLColor4 mImageColor;
LLColor4 mDisabledImageColor;
LLUIColor mFlashBgColor;
BOOL mIsToggle;
BOOL mToggleState;
BOOL mScaleImage;
LLUIColor mImageColor;
LLUIColor mDisabledImageColor;
BOOL mDropShadowedText;
bool mIsToggle;
bool mScaleImage;
BOOL mBorderEnabled;
bool mDropShadowedText;
bool mAutoResize;
bool mBorderEnabled;
bool mFlashing;
BOOL mFlashing;
LLFontGL::HAlign mHAlign;
S32 mLeftHPad;
S32 mRightHPad;
S32 mBottomVPad; // under text label
LLFontGL::HAlign mHAlign;
S32 mLeftHPad;
S32 mRightHPad;
S32 mImageOverlayTopPad;
S32 mImageOverlayBottomPad;
F32 mHoverGlowStrength;
F32 mCurGlowStrength;
/*
* Space between image_overlay and label
*/
S32 mImgOverlayLabelSpace;
BOOL mNeedsHighlight;
BOOL mCommitOnReturn;
F32 mHoverGlowStrength;
F32 mCurGlowStrength;
std::string mHelpURL;
bool mCommitOnReturn;
bool mFadeWhenDisabled;
LLPointer<LLUIImage> mImagep;
bool mForcePressedState;
bool mDisplayPressedState;
LLFrameTimer mFlashingTimer;
std::string mHelpURL;
LLFrameTimer mFlashingTimer;
bool mHandleRightMouse;
F32 mAlpha;
};
#endif // LL_LLBUTTON_H

View File

@@ -113,37 +113,27 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const std::string& name, const LLRect& rect,
LLCHECKBOXCTRL_VPAD,
LLCHECKBOXCTRL_BTN_SIZE + LLCHECKBOXCTRL_SPACING + text_width + LLCHECKBOXCTRL_HPAD,
llmax( text_height, LLCHECKBOXCTRL_BTN_SIZE ) + LLCHECKBOXCTRL_VPAD);
std::string active_true_id, active_false_id;
std::string inactive_true_id, inactive_false_id;
if (mRadioStyle)
{
active_true_id = "UIImgRadioActiveSelectedUUID";
active_false_id = "UIImgRadioActiveUUID";
inactive_true_id = "UIImgRadioInactiveSelectedUUID";
inactive_false_id = "UIImgRadioInactiveUUID";
mButton = new LLButton(std::string("Radio control button"), btn_rect,
active_false_id, active_true_id, control_which,
&LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
mButton->setDisabledImages( inactive_false_id, inactive_true_id );
mButton->setHoverGlowStrength(0.35f);
}
else
{
active_false_id = "UIImgCheckboxActiveUUID";
active_true_id = "UIImgCheckboxActiveSelectedUUID";
inactive_true_id = "UIImgCheckboxInactiveSelectedUUID";
inactive_false_id = "UIImgCheckboxInactiveUUID";
mButton = new LLButton(std::string("Checkbox control button"), btn_rect,
active_false_id, active_true_id, control_which,
&LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
mButton->setDisabledImages( inactive_false_id, inactive_true_id );
mButton->setHoverGlowStrength(0.35f);
}
std::string active_true_id = mRadioStyle ? "UIImgRadioActiveSelectedUUID" : "UIImgCheckboxActiveSelectedUUID";
std::string active_false_id = mRadioStyle ? "UIImgRadioActiveUUID" : "UIImgCheckboxActiveUUID";
std::string inactive_true_id = mRadioStyle ? "UIImgRadioInactiveSelectedUUID" : "UIImgCheckboxInactiveSelectedUUID";
std::string inactive_false_id = mRadioStyle ? "UIImgRadioInactiveUUID" : "UIImgCheckboxInactiveUUID";
std::string button_name = mRadioStyle ? "Radio control button" : "Checkbox control button";
mButton = new LLButton( button_name, btn_rect,
active_false_id, active_true_id, control_which,
&LLCheckBoxCtrl::onButtonPress, this, LLFontGL::getFontSansSerif() );
mButton->setImageDisabledSelected(LLUI::getUIImage(inactive_true_id));
mButton->setImageDisabled(LLUI::getUIImage(inactive_false_id));
mButton->setHoverGlowStrength(0.35f);
mButton->setIsToggle(TRUE);
mButton->setToggleState( initial_value );
mButton->setFollowsLeft();
mButton->setFollowsBottom();
mButton->setCommitOnReturn(FALSE);
mButton->setScaleImage(FALSE);
addChild(mButton);
}
@@ -156,22 +146,8 @@ LLCheckBoxCtrl::~LLCheckBoxCtrl()
// static
void LLCheckBoxCtrl::onButtonPress( void *userdata )
{
LLCheckBoxCtrl* self = (LLCheckBoxCtrl*) userdata;
if (self->mRadioStyle)
{
self->setValue(TRUE);
}
self->setControlValue(self->getValue());
// HACK: because buttons don't normally commit
LLCheckBoxCtrl* self = (LLCheckBoxCtrl*)userdata;
self->onCommit();
if (self->mKeyboardFocusOnClick)
{
self->setFocus( TRUE );
self->onFocusReceived();
}
}
void LLCheckBoxCtrl::onCommit()
@@ -179,6 +155,7 @@ void LLCheckBoxCtrl::onCommit()
if( getEnabled() )
{
setTentative(FALSE);
setControlValue(getValue());
LLUICtrl::onCommit();
}
}
@@ -186,7 +163,15 @@ void LLCheckBoxCtrl::onCommit()
void LLCheckBoxCtrl::setEnabled(BOOL b)
{
LLView::setEnabled(b);
mButton->setEnabled(b);
if (b)
{
mLabel->setColor( mTextEnabledColor.get() );
}
else
{
mLabel->setColor( mTextDisabledColor.get() );
}
}
void LLCheckBoxCtrl::clear()
@@ -219,21 +204,6 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
LLUICtrl::reshape(width, height, called_from_parent);
}
void LLCheckBoxCtrl::draw()
{
if (getEnabled())
{
mLabel->setColor( mTextEnabledColor );
}
else
{
mLabel->setColor( mTextDisabledColor );
}
// Draw children
LLUICtrl::draw();
}
//virtual
void LLCheckBoxCtrl::setValue(const LLSD& value )
{
@@ -246,6 +216,18 @@ LLSD LLCheckBoxCtrl::getValue() const
return mButton->getValue();
}
//virtual
void LLCheckBoxCtrl::setTentative(BOOL b)
{
mButton->setTentative(b);
}
//virtual
BOOL LLCheckBoxCtrl::getTentative() const
{
return mButton->getTentative();
}
void LLCheckBoxCtrl::setLabel( const LLStringExplicit& label )
{
mLabel->setText( label );
@@ -282,7 +264,7 @@ BOOL LLCheckBoxCtrl::isDirty() const
{
if ( mButton )
{
return (mSetValue != mButton->getToggleState());
return mButton->isDirty();
}
return FALSE; // Shouldn't get here
}
@@ -293,11 +275,12 @@ void LLCheckBoxCtrl::resetDirty()
{
if ( mButton )
{
mSetValue = mButton->getToggleState();
mButton->resetDirty();
}
}
// virtual
LLXMLNodePtr LLCheckBoxCtrl::getXML(bool save_children) const
{

View File

@@ -82,7 +82,6 @@ public:
virtual void setEnabled( BOOL b );
virtual void draw();
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
// LLUICtrl interface
@@ -91,8 +90,8 @@ public:
BOOL get() { return (BOOL)getValue().asBoolean(); }
void set(BOOL value) { setValue(value); }
virtual void setTentative(BOOL b) { mButton->setTentative(b); }
virtual BOOL getTentative() const { return mButton->getTentative(); }
virtual void setTentative(BOOL b);
virtual BOOL getTentative() const;
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
@@ -108,6 +107,9 @@ public:
void setLabel( const LLStringExplicit& label );
std::string getLabel() const;
void setFont( const LLFontGL* font ) { mFont = font; }
const LLFontGL* getFont() { return mFont; }
virtual void setControlName(const std::string& control_name, LLView* context);
virtual std::string getControlName() const;
@@ -121,8 +123,9 @@ protected:
LLButton* mButton;
LLTextBox* mLabel;
const LLFontGL* mFont;
LLColor4 mTextEnabledColor;
LLColor4 mTextDisabledColor;
LLUIColor mTextEnabledColor;
LLUIColor mTextDisabledColor;
BOOL mRadioStyle;
BOOL mInitialValue; // Value set in constructor
BOOL mSetValue; // Value set programmatically

View File

@@ -85,13 +85,13 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::
LLRect(),
LLStringUtil::null,
NULL, this);
mButton->setImageUnselected(std::string("square_btn_32x128.tga"));
mButton->setImageSelected(std::string("square_btn_selected_32x128.tga"));
mButton->setImageDisabled(std::string("square_btn_32x128.tga"));
mButton->setImageDisabledSelected(std::string("square_btn_selected_32x128.tga"));
mButton->setImageUnselected(LLUI::getUIImage("square_btn_32x128.tga"));
mButton->setImageSelected(LLUI::getUIImage("square_btn_selected_32x128.tga"));
mButton->setImageDisabled(LLUI::getUIImage("square_btn_32x128.tga"));
mButton->setImageDisabledSelected(LLUI::getUIImage("square_btn_selected_32x128.tga"));
mButton->setScaleImage(TRUE);
mButton->setMouseDownCallback(onButtonDown);
mButton->setMouseDownCallback(boost::bind(&LLComboBox::onButtonDown,this));
mButton->setFont(LLFontGL::getFontSansSerifSmall());
mButton->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
mButton->setHAlign( LLFontGL::LEFT );
@@ -110,13 +110,11 @@ LLComboBox::LLComboBox( const std::string& name, const LLRect &rect, const std::
mButton->setImageOverlay("combobox_arrow.tga", LLFontGL::RIGHT);
updateLayout();
mTopLostSignalConnection = setTopLostCallback(boost::bind(&LLComboBox::hideList, this));
}
LLComboBox::~LLComboBox()
{
// children automatically deleted, including mMenu, mButton
}
// virtual
LLXMLNodePtr LLComboBox::getXML(bool save_children) const
@@ -228,6 +226,16 @@ void LLComboBox::setEnabled(BOOL enabled)
mButton->setEnabled(enabled);
}
LLComboBox::~LLComboBox()
{
// children automatically deleted, including mMenu, mButton
// explicitly disconect this signal, since base class destructor might fire top lost
mTopLostSignalConnection.disconnect();
}
void LLComboBox::clear()
{
if (mTextEntry)
@@ -236,8 +244,6 @@ void LLComboBox::clear()
}
mButton->setLabelSelected(LLStringUtil::null);
mButton->setLabelUnselected(LLStringUtil::null);
mButton->setDisabledLabel(LLStringUtil::null);
mButton->setDisabledSelectedLabel(LLStringUtil::null);
mList->deselectAllItems();
}
@@ -437,8 +443,6 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
{
mButton->setLabelUnselected(name);
mButton->setLabelSelected(name);
mButton->setDisabledLabel(name);
mButton->setDisabledSelectedLabel(name);
}
}
@@ -481,12 +485,6 @@ void LLComboBox::onFocusLost()
LLUICtrl::onFocusLost();
}
void LLComboBox::onLostTop()
{
hideList();
}
void LLComboBox::setButtonVisible(BOOL visible)
{
mButton->setVisible(visible);
@@ -749,10 +747,10 @@ void LLComboBox::onButtonDown(void *userdata)
self->setFocus( TRUE );
// pass mouse capture on to list if button is depressed
if (self->mButton->hasMouseCapture())
/*if (self->mButton->hasMouseCapture())
{
gFocusMgr.setMouseCapture(self->mList);
}
}*/
}
else
{
@@ -1216,7 +1214,7 @@ LLFlyoutButton::LLFlyoutButton(
LLRect(), LLStringUtil::null, NULL, this);
mActionButton->setScaleImage(TRUE);
mActionButton->setClickedCallback(onActionButtonClick);
mActionButton->setClickedCallback(boost::bind(&LLFlyoutButton::onActionButtonClick, this));
mActionButton->setFollowsAll();
mActionButton->setHAlign( LLFontGL::HCENTER );
mActionButton->setLabel(label);

View File

@@ -80,7 +80,6 @@ public:
virtual void draw();
virtual void onFocusLost();
virtual void onLostTop();
virtual void setEnabled(BOOL enabled);
@@ -212,6 +211,7 @@ private:
bool mSuppressTentative;
void (*mPrearrangeCallback)(LLUICtrl*,void*);
void (*mTextEntryCallback)(LLLineEditor*, void*);
boost::signals2::connection mTopLostSignalConnection;
};
class LLFlyoutButton : public LLComboBox

View File

@@ -430,6 +430,27 @@ void LLFloater::initFloater(const std::string& title,
}
}
void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
{
mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width);
mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width);
mResizeBar[LLResizeBar::TOP]->setVisible(enable && height);
mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height);
mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width);
mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width);
mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height);
mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height);
for (S32 i = 0; i < 4; ++i)
{
mResizeHandle[i]->setVisible(enable && width && height);
mResizeHandle[i]->setEnabled(enable && width && height);
}
}
// virtual
LLFloater::~LLFloater()
{
@@ -707,6 +728,8 @@ const std::string& LLFloater::getCurrentTitle() const
void LLFloater::setTitle( const std::string& title )
{
if(mTitle == title)
return;
mTitle = title;
applyTitle();
}
@@ -1542,10 +1565,12 @@ void LLFloater::setCanResize(BOOL can_resize)
{
for (S32 i = 0; i < 4; i++)
{
removeChild(mResizeBar[i], TRUE);
removeChild(mResizeBar[i]);
delete mResizeBar[i];
mResizeBar[i] = NULL;
removeChild(mResizeHandle[i], TRUE);
removeChild(mResizeHandle[i]);
delete mResizeHandle[i];
mResizeHandle[i] = NULL;
}
}
@@ -1611,6 +1636,7 @@ void LLFloater::setCanResize(BOOL can_resize)
mMinHeight,
LLResizeHandle::LEFT_TOP );
addChild(mResizeHandle[3]);
enableResizeCtrls(can_resize);
}
mResizable = can_resize;
}
@@ -1714,8 +1740,8 @@ void LLFloater::buildButtons()
buttonp->setFollowsRight();
buttonp->setToolTip( sButtonToolTips[i] );
buttonp->setImageColor(LLUI::sColorsGroup->getColor("FloaterButtonImageColor"));
buttonp->setHoverImages(sButtonPressedImageNames[i],
sButtonPressedImageNames[i]);
buttonp->setImageHoverSelected(LLUI::getUIImage(sButtonPressedImageNames[i]));
buttonp->setImageHoverUnselected(LLUI::getUIImage(sButtonPressedImageNames[i]));
buttonp->setScaleImage(TRUE);
buttonp->setSaveToXML(false);
addChild(buttonp);
@@ -2459,8 +2485,12 @@ void LLFloaterView::pushVisibleAll(BOOL visible, const skip_list_t& skip_list)
void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
{
for (child_list_const_iter_t child_iter = getChildList()->begin();
child_iter != getChildList()->end(); ++child_iter)
// make a copy of the list since some floaters change their
// order in the childList when changing visibility.
child_list_t child_list_copy = *getChildList();
for (child_list_const_iter_t child_iter = child_list_copy.begin();
child_iter != child_list_copy.end(); ++child_iter)
{
LLView *view = *child_iter;
if (skip_list.find(view) == skip_list.end())

View File

@@ -250,6 +250,7 @@ public:
static BOOL getEditModeEnabled() { return sEditModeEnabled; }
static LLMultiFloater* getFloaterHost() {return sHostp; }
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
protected:
virtual void bringToFront(S32 x, S32 y);

View File

@@ -2,31 +2,25 @@
* @file llfocusmgr.cpp
* @brief LLFocusMgr base class
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* 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
* Copyright (C) 2010, Linden Research, Inc.
*
* 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
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -38,13 +32,11 @@
const F32 FOCUS_FADE_TIME = 0.3f;
// NOTE: the LLFocusableElement implementation has been here from lluictrl.cpp.
LLFocusableElement::LLFocusableElement()
: mFocusLostCallback(NULL),
mFocusReceivedCallback(NULL),
mFocusChangedCallback(NULL),
mFocusCallbackUserData(NULL)
mTopLostCallback(NULL)
{
}
@@ -63,31 +55,27 @@ BOOL LLFocusableElement::handleUnicodeChar(llwchar uni_char, BOOL called_from_pa
// virtual
LLFocusableElement::~LLFocusableElement()
{
delete mFocusLostCallback;
delete mFocusReceivedCallback;
delete mFocusChangedCallback;
delete mTopLostCallback;
}
void LLFocusableElement::onFocusReceived()
{
if( mFocusReceivedCallback )
{
mFocusReceivedCallback( this, mFocusCallbackUserData );
}
if( mFocusChangedCallback )
{
mFocusChangedCallback( this, mFocusCallbackUserData );
}
if (mFocusReceivedCallback) (*mFocusReceivedCallback)(this);
if (mFocusChangedCallback) (*mFocusChangedCallback)(this);
}
void LLFocusableElement::onFocusLost()
{
if( mFocusLostCallback )
{
mFocusLostCallback( this, mFocusCallbackUserData );
}
if (mFocusLostCallback) (*mFocusLostCallback)(this);
if (mFocusChangedCallback) (*mFocusChangedCallback)(this);
}
if( mFocusChangedCallback )
{
mFocusChangedCallback( this, mFocusCallbackUserData );
}
void LLFocusableElement::onTopLost()
{
if (mTopLostCallback) (*mTopLostCallback)(this);
}
BOOL LLFocusableElement::hasFocus() const
@@ -99,28 +87,63 @@ void LLFocusableElement::setFocus(BOOL b)
{
}
boost::signals2::connection LLFocusableElement::setFocusLostCallback( const focus_signal_t::slot_type& cb)
{
if (!mFocusLostCallback) mFocusLostCallback = new focus_signal_t();
return mFocusLostCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setFocusReceivedCallback(const focus_signal_t::slot_type& cb)
{
if (!mFocusReceivedCallback) mFocusReceivedCallback = new focus_signal_t();
return mFocusReceivedCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setFocusChangedCallback(const focus_signal_t::slot_type& cb)
{
if (!mFocusChangedCallback) mFocusChangedCallback = new focus_signal_t();
return mFocusChangedCallback->connect(cb);
}
boost::signals2::connection LLFocusableElement::setTopLostCallback(const focus_signal_t::slot_type& cb)
{
if (!mTopLostCallback) mTopLostCallback = new focus_signal_t();
return mTopLostCallback->connect(cb);
}
typedef std::list<LLHandle<LLView> > view_handle_list_t;
typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
struct LLFocusMgr::Impl
{
// caching list of keyboard focus ancestors for calling onFocusReceived and onFocusLost
view_handle_list_t mCachedKeyboardFocusList;
focus_history_map_t mFocusHistory;
};
LLFocusMgr gFocusMgr;
LLFocusMgr::LLFocusMgr()
:
mLockedView( NULL ),
: mLockedView( NULL ),
mMouseCaptor( NULL ),
mKeyboardFocus( NULL ),
mLastKeyboardFocus( NULL ),
mDefaultKeyboardFocus( NULL ),
mKeystrokesOnly(FALSE),
mTopCtrl( NULL ),
mFocusWeight(0.f),
mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true
#ifdef _DEBUG
, mMouseCaptorName("none")
, mKeyboardFocusName("none")
, mTopCtrlName("none")
#endif
mAppHasFocus(TRUE), // Macs don't seem to notify us that we've gotten focus, so default to true
mImpl(new LLFocusMgr::Impl)
{
}
LLFocusMgr::~LLFocusMgr()
{
mImpl->mFocusHistory.clear();
delete mImpl;
mImpl = NULL;
}
void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
{
@@ -151,6 +174,12 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only)
{
// notes if keyboard focus is changed again (by onFocusLost/onFocusReceived)
// making the rest of our processing unnecessary since it will already be
// handled by the recursive call
static bool focus_dirty;
focus_dirty = false;
if (mLockedView &&
(new_focus == NULL ||
(new_focus != mLockedView
@@ -162,8 +191,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
return;
}
//llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl;
mKeystrokesOnly = keystrokes_only;
if( new_focus != mKeyboardFocus )
@@ -171,23 +198,58 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
mLastKeyboardFocus = mKeyboardFocus;
mKeyboardFocus = new_focus;
if( mLastKeyboardFocus )
// list of the focus and it's ancestors
view_handle_list_t old_focus_list = mImpl->mCachedKeyboardFocusList;
view_handle_list_t new_focus_list;
// walk up the tree to root and add all views to the new_focus_list
for (LLView* ctrl = dynamic_cast<LLView*>(mKeyboardFocus); ctrl; ctrl = ctrl->getParent())
{
mLastKeyboardFocus->onFocusLost();
new_focus_list.push_back(ctrl->getHandle());
}
// clear out any existing flash
if (new_focus)
// remove all common ancestors since their focus is unchanged
while (!new_focus_list.empty() &&
!old_focus_list.empty() &&
new_focus_list.back() == old_focus_list.back())
{
mFocusWeight = 0.f;
new_focus->onFocusReceived();
new_focus_list.pop_back();
old_focus_list.pop_back();
}
mFocusTimer.reset();
#ifdef _DEBUG
LLUICtrl* focus_ctrl = dynamic_cast<LLUICtrl*>(new_focus);
mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none");
#endif
// walk up the old focus branch calling onFocusLost
// we bubble up the tree to release focus, and back down to add
for (view_handle_list_t::iterator old_focus_iter = old_focus_list.begin();
old_focus_iter != old_focus_list.end() && !focus_dirty;
old_focus_iter++)
{
LLView* old_focus_view = old_focus_iter->get();
if (old_focus_view)
{
mImpl->mCachedKeyboardFocusList.pop_front();
old_focus_view->onFocusLost();
}
}
// walk down the new focus branch calling onFocusReceived
for (view_handle_list_t::reverse_iterator new_focus_riter = new_focus_list.rbegin();
new_focus_riter != new_focus_list.rend() && !focus_dirty;
new_focus_riter++)
{
LLView* new_focus_view = new_focus_riter->get();
if (new_focus_view)
{
mImpl->mCachedKeyboardFocusList.push_front(new_focus_view->getHandle());
new_focus_view->onFocusReceived();
}
}
// if focus was changed as part of an onFocusLost or onFocusReceived call
// stop iterating on current list since it is now invalid
if (focus_dirty)
{
return;
}
// If we've got a default keyboard focus, and the caller is
// releasing keyboard focus, move to the default.
@@ -212,7 +274,7 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
if (focus_subtree)
{
LLView* focused_view = dynamic_cast<LLView*>(mKeyboardFocus);
mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>();
mImpl->mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>();
}
}
@@ -220,6 +282,8 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
{
lockFocus();
}
focus_dirty = true;
}
@@ -241,7 +305,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 )
@@ -268,65 +332,42 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f
if( mKeyboardFocus == focus )
{
mKeyboardFocus = NULL;
#ifdef _DEBUG
mKeyboardFocusName = std::string("none");
#endif
}
}
void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )
{
//if (mFocusLocked)
//{
// return;
//}
if( new_captor != mMouseCaptor )
{
LLMouseHandler* old_captor = mMouseCaptor;
mMouseCaptor = new_captor;
/*
if (new_captor)
if (LLView::sDebugMouseHandling)
{
if ( new_captor->getName() == "Stickto")
if (new_captor)
{
llinfos << "New mouse captor: " << new_captor->getName() << llendl;
}
else
{
llinfos << "New mouse captor: " << new_captor->getName() << llendl;
llinfos << "New mouse captor: NULL" << llendl;
}
}
else
{
llinfos << "New mouse captor: NULL" << llendl;
}
*/
if( old_captor )
{
old_captor->onMouseCaptureLost();
}
#ifdef _DEBUG
mMouseCaptorName = new_captor ? new_captor->getName() : std::string("none");
#endif
}
}
void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor )
{
//if (mFocusLocked)
//{
// return;
//}
if( mMouseCaptor == captor )
{
mMouseCaptor = NULL;
#ifdef _DEBUG
mMouseCaptorName = std::string("none");
#endif
}
}
@@ -355,13 +396,9 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top )
{
mTopCtrl = new_top;
#ifdef _DEBUG
mTopCtrlName = new_top ? new_top->getName() : std::string("none");
#endif
if (old_top)
{
old_top->onLostTop();
old_top->onTopLost();
}
}
}
@@ -371,9 +408,6 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view )
if( mTopCtrl == top_view )
{
mTopCtrl = NULL;
#ifdef _DEBUG
mTopCtrlName = std::string("none");
#endif
}
}
@@ -389,12 +423,13 @@ void LLFocusMgr::unlockFocus()
F32 LLFocusMgr::getFocusFlashAmt() const
{
return clamp_rescale(getFocusTime(), 0.f, FOCUS_FADE_TIME, mFocusWeight, 0.f);
return clamp_rescale(mFocusFlashTimer.getElapsedTimeF32(), 0.f, FOCUS_FADE_TIME, 1.f, 0.f);
}
LLColor4 LLFocusMgr::getFocusColor() const
{
LLColor4 focus_color = lerp(LLUI::sColorsGroup->getColor( "FocusColor" ), LLColor4::white, getFocusFlashAmt());
static LLCachedControl<LLColor4> focus_color_cached(*LLUI::sColorsGroup,"FocusColor", LLColor4::white);
LLColor4 focus_color = lerp(focus_color_cached, LLColor4::white, getFocusFlashAmt());
// de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem)
if (!mAppHasFocus)
{
@@ -405,8 +440,7 @@ LLColor4 LLFocusMgr::getFocusColor() const
void LLFocusMgr::triggerFocusFlash()
{
mFocusTimer.reset();
mFocusWeight = 1.f;
mFocusFlashTimer.reset();
}
void LLFocusMgr::setAppHasFocus(BOOL focus)
@@ -428,8 +462,8 @@ LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const
{
if (subtree_root)
{
focus_history_map_t::const_iterator found_it = mFocusHistory.find(subtree_root->getHandle());
if (found_it != mFocusHistory.end())
focus_history_map_t::const_iterator found_it = mImpl->mFocusHistory.find(subtree_root->getHandle());
if (found_it != mImpl->mFocusHistory.end())
{
// found last focus for this subtree
return static_cast<LLUICtrl*>(found_it->second.get());
@@ -442,6 +476,6 @@ void LLFocusMgr::clearLastFocusForGroup(LLView* subtree_root)
{
if (subtree_root)
{
mFocusHistory.erase(subtree_root->getHandle());
mImpl->mFocusHistory.erase(subtree_root->getHandle());
}
}

View File

@@ -2,31 +2,25 @@
* @file llfocusmgr.h
* @brief LLFocusMgr base class
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* 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
* Copyright (C) 2010, Linden Research, Inc.
*
* 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
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* 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.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -38,12 +32,12 @@
#include "llstring.h"
#include "llframetimer.h"
#include "llui.h"
#include "llhandle.h"
class LLUICtrl;
class LLMouseHandler;
class LLView;
// NOTE: the LLFocusableElement class declaration has been moved here from lluictrl.h.
class LLFocusableElement
{
friend class LLFocusMgr; // allow access to focus change handlers
@@ -54,21 +48,25 @@ public:
virtual void setFocus( BOOL b );
virtual BOOL hasFocus() const;
void setFocusLostCallback(void (*cb)(LLFocusableElement* caller, void*), void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; }
void setFocusReceivedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; }
void setFocusChangedCallback( void (*cb)(LLFocusableElement*, void*), void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; }
typedef boost::signals2::signal<void(LLFocusableElement*)> focus_signal_t;
boost::signals2::connection setFocusLostCallback( const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusChangedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setTopLostCallback(const focus_signal_t::slot_type& cb);
// These were brought up the hierarchy from LLView so that we don't have to use dynamic_cast when dealing with keyboard focus.
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere
protected:
virtual void onFocusReceived();
virtual void onFocusLost();
void (*mFocusLostCallback)( LLFocusableElement* caller, void* userdata );
void (*mFocusReceivedCallback)( LLFocusableElement* ctrl, void* userdata );
void (*mFocusChangedCallback)( LLFocusableElement* ctrl, void* userdata );
void* mFocusCallbackUserData;
focus_signal_t* mFocusLostCallback;
focus_signal_t* mFocusReceivedCallback;
focus_signal_t* mFocusChangedCallback;
focus_signal_t* mTopLostCallback;
};
@@ -76,7 +74,7 @@ class LLFocusMgr
{
public:
LLFocusMgr();
~LLFocusMgr() { mFocusHistory.clear(); }
~LLFocusMgr();
// Mouse Captor
void setMouseCapture(LLMouseHandler* new_captor); // new_captor = NULL to release the mouse.
@@ -93,7 +91,7 @@ public:
BOOL getKeystrokesOnly() { return mKeystrokesOnly; }
void setKeystrokesOnly(BOOL keystrokes_only) { mKeystrokesOnly = keystrokes_only; }
F32 getFocusTime() const { return mFocusTimer.getElapsedTimeF32(); }
F32 getFocusTime() const { return mFocusFlashTimer.getElapsedTimeF32(); }
F32 getFocusFlashAmt() const;
S32 getFocusFlashWidth() const { return llround(lerp(1.f, 3.f, getFocusFlashAmt())); }
LLColor4 getFocusColor() const;
@@ -121,6 +119,9 @@ public:
void unlockFocus();
BOOL focusLocked() const { return mLockedView != NULL; }
struct Impl;
private:
LLUICtrl* mLockedView;
@@ -132,23 +133,15 @@ private:
LLFocusableElement* mLastKeyboardFocus; // who last had focus
LLFocusableElement* mDefaultKeyboardFocus;
BOOL mKeystrokesOnly;
// Top View
LLUICtrl* mTopCtrl;
LLFrameTimer mFocusTimer;
F32 mFocusWeight;
LLFrameTimer mFocusFlashTimer;
BOOL mAppHasFocus;
typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;
focus_history_map_t mFocusHistory;
#ifdef _DEBUG
std::string mMouseCaptorName;
std::string mKeyboardFocusName;
std::string mTopCtrlName;
#endif
Impl * mImpl;
};
extern LLFocusMgr gFocusMgr;

View File

@@ -104,7 +104,6 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
:
LLUICtrl( name, rect, TRUE, commit_callback, userdata, FOLLOWS_TOP | FOLLOWS_LEFT ),
mMaxLengthBytes(max_length_bytes),
mPopupMenuHandle(),
mCursorPos( 0 ),
mScrollHPos( 0 ),
mTextPadLeft(0),
@@ -140,7 +139,8 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
mHaveHistory(FALSE),
mImage( sImage ),
mReplaceNewlinesWithSpaces( TRUE ),
mSpellCheckable( FALSE )
mSpellCheckable( FALSE ),
mContextMenuHandle()
{
llassert( max_length_bytes > 0 );
@@ -156,7 +156,8 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
mGLFont = LLFontGL::getFontSansSerifSmall();
}
setFocusLostCallback(focus_lost_callback);
if(focus_lost_callback)
setFocusLostCallback(boost::bind(focus_lost_callback,_1,(void*)NULL));
setTextPadding(0, 0);
@@ -185,35 +186,30 @@ LLLineEditor::LLLineEditor(const std::string& name, const LLRect& rect,
{
menu = new LLMenuGL(LLStringUtil::null);
}*/
menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
menu->appendSeparator("Spelsep");
menu->addChild(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
menu->addChild(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
menu->addChild(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
menu->addChild(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
menu->addChild(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
menu->addSeparator();
//menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor"));
menu->setCanTearOff(FALSE);
menu->setVisible(FALSE);
mPopupMenuHandle = menu->getHandle();
setContextMenu(menu);
}
LLLineEditor::~LLLineEditor()
{
mCommitOnFocusLost = FALSE;
// calls onCommit() while LLLineEditor still valid
gFocusMgr.releaseFocusIfNeeded( this );
if( gEditMenuHandler == this )
{
gEditMenuHandler = NULL;
}
LLView::deleteViewByHandle(mPopupMenuHandle);
}
void LLLineEditor::onFocusReceived()
{
gEditMenuHandler = this;
LLUICtrl::onFocusReceived();
updateAllowingLanguageInput();
}
@@ -645,105 +641,6 @@ BOOL LLLineEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
BOOL LLLineEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
setFocus(TRUE);
//setCursorAtLocalPos( x);
S32 wordStart = 0;
S32 wordLen = 0;
S32 pos = calculateCursorFromMouse(x);
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu)
{
if(menu->isOpen())
{
menu->setVisible(FALSE);
}
for (int i = 0;i<(int)suggestionMenuItems.size();i++)
{
SpellMenuBind * tempBind = suggestionMenuItems[i];
if(tempBind)
{
menu->remove((LLMenuItemCallGL *)tempBind->menuItem);
((LLMenuItemCallGL *)tempBind->menuItem)->die();
//delete tempBind->menuItem;
//tempBind->menuItem = NULL;
delete tempBind;
}
}
suggestionMenuItems.clear();
// spell_check="true" in xui
menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable);
if (!mReadOnly && mSpellCheckable)
{
// search for word matches
bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen);
if (is_word_part)
{
const LLWString& text = mText.getWString();
std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen));
if (!glggHunSpell->isSpelledRight(selectedWord))
{
//misspelled word here, and you have just right clicked on it!
std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
for (int i = 0; i<(int)suggs.size() ;i++)
{
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
tempStruct->word = suggs[i];
tempStruct->wordPositionEnd = wordStart + wordLen;
tempStruct->wordPositionStart=wordStart;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_correct, NULL, tempStruct);
//new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
tempStruct->word = selectedWord;
tempStruct->wordPositionEnd = wordStart + wordLen;
tempStruct->wordPositionStart=wordStart;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
"Add Word", spell_add, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
}
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
if (glggHunSpell->getSpellCheckHighlight())
{
tempStruct->word = "Hide Misspellings";
}
else
{
tempStruct->word = "Show Misspellings";
}
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_show, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
}
mLastContextMenuX = x;
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
}
return TRUE;
}
BOOL LLLineEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
// Check first whether the "clear search" button wants to deal with this.
@@ -835,6 +732,16 @@ BOOL LLLineEditor::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
return TRUE;
}
BOOL LLLineEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
if (!LLUICtrl::handleRightMouseDown(x, y, mask))
{
showContextMenu(x, y);
}
return TRUE;
}
BOOL LLLineEditor::handleHover(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
@@ -1615,7 +1522,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask )
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
if (menu && menu->isOpen())
{
LLMenuGL::sMenuContainer->hideMenus();
@@ -1697,7 +1604,7 @@ BOOL LLLineEditor::handleUnicodeCharHere(llwchar uni_char)
{
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
if (menu && menu->isOpen())
{
LLMenuGL::sMenuContainer->hideMenus();
@@ -2060,7 +1967,7 @@ void LLLineEditor::draw()
// Make sure the IME is in the right place
S32 pixels_after_scroll = findPixelNearestPos(); // RCalculcate for IME position
LLRect screen_pos = getScreenRect();
LLRect screen_pos = calcScreenRect();
LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - UI_LINEEDITOR_V_PAD );
ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
@@ -3069,6 +2976,121 @@ LLWString LLLineEditor::getConvertedText() const
return text;
}
void LLLineEditor::showContextMenu(S32 x, S32 y)
{
LLMenuGL* menu = static_cast<LLMenuGL*>(mContextMenuHandle.get());
if (menu)
{
gEditMenuHandler = this;
/*S32 screen_x, screen_y;
localPointToScreen(x, y, &screen_x, &screen_y);
menu->show(screen_x, screen_y);*/
//setCursorAtLocalPos( x);
S32 wordStart = 0;
S32 wordLen = 0;
S32 pos = calculateCursorFromMouse(x);
LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
if (menu)
{
if(menu->isOpen())
{
menu->setVisible(FALSE);
}
for (int i = 0;i<(int)suggestionMenuItems.size();i++)
{
SpellMenuBind * tempBind = suggestionMenuItems[i];
if(tempBind)
{
menu->removeChild((LLMenuItemCallGL *)tempBind->menuItem);
((LLMenuItemCallGL *)tempBind->menuItem)->die();
//delete tempBind->menuItem;
//tempBind->menuItem = NULL;
delete tempBind;
}
}
suggestionMenuItems.clear();
// spell_check="true" in xui
menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable);
if (!mReadOnly && mSpellCheckable)
{
// search for word matches
bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen);
if (is_word_part)
{
const LLWString& text = mText.getWString();
std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen));
if (!glggHunSpell->isSpelledRight(selectedWord))
{
//misspelled word here, and you have just right clicked on it!
std::vector<std::string> suggs = glggHunSpell->getSuggestionList(selectedWord);
for (int i = 0; i<(int)suggs.size() ;i++)
{
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
tempStruct->word = suggs[i];
tempStruct->wordPositionEnd = wordStart + wordLen;
tempStruct->wordPositionStart=wordStart;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_correct, NULL, tempStruct);
//new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->addChild(suggMenuItem);
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
tempStruct->word = selectedWord;
tempStruct->wordPositionEnd = wordStart + wordLen;
tempStruct->wordPositionStart=wordStart;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
"Add Word", spell_add, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->addChild(suggMenuItem);
}
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
if (glggHunSpell->getSpellCheckHighlight())
{
tempStruct->word = "Hide Misspellings";
}
else
{
tempStruct->word = "Show Misspellings";
}
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_show, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->addChild(suggMenuItem);
}
mLastContextMenuX = x;
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
LLMenuGL::showPopup(this, menu, x, y);
}
}
}
void LLLineEditor::setContextMenu(LLMenuGL* new_context_menu)
{
if (new_context_menu)
mContextMenuHandle = new_context_menu->getHandle();
else
mContextMenuHandle.markDead();
}
static LLRegisterWidget<LLSearchEditor> r2("search_editor");

View File

@@ -56,6 +56,7 @@
class LLFontGL;
class LLLineEditorRollback;
class LLButton;
class LLMenuGL;
typedef BOOL (*LLLinePrevalidateFunc)(const LLWString &wstr);
@@ -79,6 +80,9 @@ public:
LLViewBorder::EStyle border_style = LLViewBorder::STYLE_LINE,
S32 border_thickness = 1);
protected:
void showContextMenu(S32 x, S32 y);
public:
virtual ~LLLineEditor();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
@@ -252,7 +256,9 @@ public:
void updateHistory(); // stores current line in history
void setReplaceNewlinesWithSpaces(BOOL replace);
void setContextMenu(LLMenuGL* new_context_menu);
private:
// private helper methods
@@ -285,7 +291,6 @@ private:
virtual S32 getPreeditFontSize() const;
protected:
LLHandle<LLView> mPopupMenuHandle;
LLUIString mText; // The string being edited.
std::string mPrevText; // Saved string for 'ESC' revert
LLUIString mLabel; // text label that is visible when no user text provided
@@ -359,6 +364,8 @@ protected:
std::vector<S32> mPreeditPositions;
LLPreeditor::standouts_t mPreeditStandouts;
LLHandle<LLView> mContextMenuHandle;
private:
// Utility on top of LLUI::getUIImage, looks up a named image in a given XML node and returns it if possible
// or returns a given default image if anything in the process fails.

File diff suppressed because it is too large Load Diff

View File

@@ -76,32 +76,40 @@ typedef void (*label_callback)(std::string&,void*);
// The LLMenuItemGL represents a single menu item in a menu.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLMenuItemGL : public LLView
class LLMenuItemGL : public LLUICtrl
{
public:
// static functions to control the global color scheme.
static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; }
/*static void setEnabledColor( const LLColor4& color ) { sEnabledColor = color; }
static const LLColor4& getEnabledColor() { return sEnabledColor; }
static void setDisabledColor( const LLColor4& color ) { sDisabledColor = color; }
static const LLColor4& getDisabledColor() { return sDisabledColor; }
static void setHighlightBGColor( const LLColor4& color ) { sHighlightBackground = color; }
static const LLColor4& getHighlightBGColor() { return sHighlightBackground; }
static void setHighlightFGColor( const LLColor4& color ) { sHighlightForeground = color; }
static const LLColor4& getHighlightFGColor() { return sHighlightForeground; }
static const LLColor4& getHighlightFGColor() { return sHighlightForeground; }*/
LLMenuItemGL( const std::string& name, const std::string& label, KEY key = KEY_NONE, MASK = MASK_NONE );
virtual ~LLMenuItemGL() {};
virtual ~LLMenuItemGL();
virtual void setValue(const LLSD& value) { setLabel(value.asString()); }
virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual std::string getType() const { return "item"; }
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ void handleVisibilityChange(BOOL new_visibility);
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
// LLUICtrl overrides
/*virtual*/ void setValue(const LLSD& value);
/*virtual*/ LLSD getValue() const;
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
LLColor4 getHighlightBgColor() { return mHighlightBackground; }
void setJumpKey(KEY key);
KEY getJumpKey() const { return mJumpKey; }
@@ -115,8 +123,8 @@ public:
virtual U32 getNominalHeight( void ) const;
// Marks item as not needing space for check marks or accelerator keys
virtual void setBriefItem(BOOL brief) { mBriefItem = brief; }
virtual BOOL isBriefItem() const { return mBriefItem; }
virtual void setBriefItem(BOOL brief);
virtual BOOL isBriefItem() const;
virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp);
void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; }
@@ -128,7 +136,7 @@ public:
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
// Get the parent menu for this item
virtual class LLMenuGL* getMenu();
virtual class LLMenuGL* getMenu() const;
// returns the normal width of this control in pixels - this is
// used for calculating the widest item, as well as for horizontal
@@ -167,6 +175,7 @@ public:
virtual BOOL handleKeyHere( KEY key, MASK mask );
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
virtual void draw( void );
BOOL getHover() const { return mGotHover; }
@@ -193,13 +202,19 @@ protected:
LLUIString mDrawAccelLabel;
LLUIString mDrawBranchLabel;
LLColor4 mEnabledColor;
LLColor4 mDisabledColor;
LLColor4 mHighlightBackground;
LLColor4 mHighlightForeground;
BOOL mHighlight;
private:
public:
static LLColor4 sEnabledColor;
static LLColor4 sDisabledColor;
static LLColor4 sHighlightBackground;
static LLColor4 sHighlightForeground;
private:
// Keyboard and mouse variables
BOOL mAllowKeyRepeat;
BOOL mGotHover;
@@ -216,6 +231,30 @@ private:
KEY mJumpKey;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemSeparatorGL
//
// This class represents a separator.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLMenuItemSeparatorGL : public LLMenuItemGL
{
public:
LLMenuItemSeparatorGL( const std::string &name = std::string() );
virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual std::string getType() const { return "separator"; }
// doIt() - do the primary funcationality of the menu item.
virtual void doIt( void ) {}
virtual void draw( void );
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 U32 getNominalHeight( void ) const;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLMenuItemCallGL
@@ -278,6 +317,9 @@ public:
void setUserData(void *userdata) { mUserData = userdata; }
void* getUserData() const { return mUserData; }
protected:
void updateEnabled( void );
public:
// called to rebuild the draw label
virtual void buildDrawLabel( void );
@@ -285,7 +327,8 @@ public:
virtual void doIt( void );
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
virtual BOOL handleKeyHere(KEY key, MASK mask);
//virtual void draw();
@@ -403,24 +446,35 @@ class LLMenuGL
// TODO: The menu and menu item classes share a great deal of functionality and perhaps should be united.
// I think it may make the most sense to make LLMenuGL be a subclass of LLMenuItemGL. -MG
{
public:
// textual artwork which menugl-imitators may want to match
static const std::string BOOLEAN_TRUE_PREFIX;
static const std::string BRANCH_SUFFIX;
static const std::string ARROW_UP;
static const std::string ARROW_DOWN;
protected:
// let branching menu items use my protected traversal methods
friend class LLMenuItemBranchGL;
public:
LLMenuGL( const std::string& name, const std::string& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>());
LLMenuGL( const std::string& label, LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>() );
LLMenuGL( const std::string& name, const std::string& label);
LLMenuGL( const std::string& label);
virtual ~LLMenuGL( void );
virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
void parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory *factory);
// LLView Functionality
virtual BOOL handleUnicodeCharHere( llwchar uni_char );
virtual BOOL handleHover( S32 x, S32 y, MASK mask );
virtual void draw( void );
/*virtual*/ BOOL handleUnicodeCharHere( llwchar uni_char );
/*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
/*virtual*/ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
/*virtual*/ void draw( void );
virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color);
virtual void setVisible(BOOL visible);
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
/*virtual*/ void removeChild( LLView* ctrl);
/*virtual*/ BOOL postBuild();
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
@@ -437,23 +491,10 @@ public:
void setBackgroundColor( const LLColor4& color ) { mBackgroundColor = color; }
const LLColor4& getBackgroundColor() const { return mBackgroundColor; }
void setBackgroundVisible( BOOL b ) { mBgVisible = b; }
void setCanTearOff(BOOL tear_off, LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>());
// Add the menu item to this menu.
virtual BOOL append( LLMenuItemGL* item );
// Remove a menu item from this menu.
virtual BOOL remove( LLMenuItemGL* item );
// *NOTE:Mani - appendNoArrange() should be removed when merging to skinning/viewer2.0
// Its added as a fix to a viewer 1.23 bug that has already been address by skinning work.
virtual BOOL appendNoArrange( LLMenuItemGL* item );
void setCanTearOff(BOOL tear_off);
// add a separator to this menu
virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null );
// add a menu - this will create a cascading menu
virtual BOOL appendMenu( LLMenuGL* menu );
virtual BOOL addSeparator();
// for branching menu items, bring sub menus up to root level of menu hierarchy
virtual void updateParent( LLView* parentp );
@@ -477,19 +518,17 @@ public:
virtual BOOL isOpen();
void needsArrange() { mNeedsArrange = TRUE; }
// Shape this menu to fit the current state of the children, and
// adjust the child rects to fit. This is called automatically
// when you add items. *FIX: We may need to deal with visibility
// arrangement.
virtual void arrange( void );
void arrangeAndClear( void );
// remove all items on the menu
void empty( void );
// Rearrange the components, and do the right thing if the menu doesn't
// fit in the bounds.
// virtual void arrangeWithBounds(LLRect bounds);
void setItemLastSelected(LLMenuItemGL* item); // must be in menu
U32 getItemCount(); // number of menu items
LLMenuItemGL* getItem(S32 number); // 0 = first item
@@ -510,8 +549,8 @@ public:
// Whether to drop shadow menu bar
void setDropShadowed( const BOOL shadowed );
void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item; }
LLMenuItemGL* getParentMenuItem() const { return mParentMenuItem; }
void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item->getHandle(); }
LLMenuItemGL* getParentMenuItem() const { return dynamic_cast<LLMenuItemGL*>(mParentMenuItem.get()); }
void setTornOff(BOOL torn_off);
BOOL getTornOff() { return mTornOff; }
@@ -524,15 +563,26 @@ public:
static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; }
static BOOL getKeyboardMode() { return sKeyboardMode; }
S32 getShortcutPad() { return mShortcutPad; }
BOOL isScrollable() const { return FALSE; }
static class LLMenuHolderGL* sMenuContainer;
bool isScrollPositionOnShowReset() { return false; }
protected:
void createSpilloverBranch();
void cleanupSpilloverBranch();
// Add the menu item to this menu.
virtual BOOL append( LLMenuItemGL* item );
// add a menu - this will create a cascading menu
virtual BOOL appendMenu( LLMenuGL* menu );
// TODO: create accessor methods for these?
typedef std::list< LLMenuItemGL* > item_list_t;
item_list_t mItems;
LLMenuItemGL*mFirstVisibleItem;
typedef std::map<KEY, LLMenuItemGL*> navigation_key_map_t;
navigation_key_map_t mJumpKeys;
S32 mLastMouseX;
@@ -541,6 +591,7 @@ protected:
S32 mMouseVelY;
BOOL mHorizontalLayout;
BOOL mKeepFixedSize;
BOOL mNeedsArrange;
private:
static LLColor4 sDefaultBackgroundColor;
@@ -548,17 +599,17 @@ private:
LLColor4 mBackgroundColor;
BOOL mBgVisible;
LLMenuItemGL* mParentMenuItem;
LLHandle<LLView> mParentMenuItem;
LLUIString mLabel;
BOOL mDropShadowed; // Whether to drop shadow
BOOL mHasSelection;
bool mHasSelection;
LLFrameTimer mFadeTimer;
BOOL mTornOff;
class LLMenuItemTearOffGL* mTearOffItem;
class LLMenuItemBranchGL* mSpilloverBranch;
LLMenuGL* mSpilloverMenu;
LLHandle<LLFloater> mParentFloaterHandle;
KEY mJumpKey;
S32 mShortcutPad;
}; // end class LLMenuGL
@@ -604,11 +655,11 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL isActive() const { return isOpen() && getBranch()->getHighlightedItem(); }
virtual BOOL isActive() const;
virtual BOOL isOpen() const { return getBranch() && getBranch()->isOpen(); }
virtual BOOL isOpen() const;
LLMenuGL *getBranch() const { return (LLMenuGL*)(mBranch.get()); }
LLMenuGL* getBranch() const { return (LLMenuGL*)mBranchHandle.get(); }
virtual void updateBranchParent( LLView* parentp );
@@ -624,7 +675,7 @@ public:
virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
private:
LLHandle<LLView> mBranch;
LLHandle<LLView> mBranchHandle;
}; // end class LLMenuItemBranchGL
@@ -646,6 +697,9 @@ public:
void initXML(LLXMLNodePtr node, LLView *context, LLUICtrlFactory *factory);
// LLView Functionality
// hide separators. they are added to 'pad' in empty cells.
virtual bool addChild(LLView* view, S32 tab_group = 0);
// can't set visibility directly, must call show or hide
virtual void setVisible(BOOL visible);
@@ -657,8 +711,10 @@ public:
virtual void draw();
virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color);
private:
virtual BOOL append(LLMenuItemGL* item);
virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null );
public:
virtual BOOL addSeparator();
BOOL appendPieMenu(LLPieMenu *menu);
@@ -703,23 +759,17 @@ public:
virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleJumpKey(KEY key);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
void setVisible(BOOL visible);
/*virtual*/ BOOL handleAcceleratorKey(KEY key, MASK mask);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ BOOL handleJumpKey(KEY key);
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
// rearrange the child rects so they fit the shape of the menu
// bar.
virtual void arrange( void );
virtual void draw();
virtual BOOL jumpKeysActive();
/*virtual*/ void draw();
/*virtual*/ BOOL jumpKeysActive();
// add a vertical separator to this menu
virtual BOOL appendSeparator( const std::string &separator_name = LLStringUtil::null );
// add a menu - this will create a drop down menu.
virtual BOOL appendMenu( LLMenuGL* menu );
virtual BOOL addSeparator();
// LLView Functionality
virtual BOOL handleHover( S32 x, S32 y, MASK mask );
@@ -730,6 +780,12 @@ public:
void resetMenuTrigger() { mAltKeyTrigger = FALSE; }
private:
// add a menu - this will create a drop down menu.
virtual BOOL appendMenu( LLMenuGL* menu );
// rearrange the child rects so they fit the shape of the menu
// bar.
virtual void arrange( void );
void checkMenuTrigger();
std::list <LLKeyBinding*> mAccelerators;
@@ -757,11 +813,20 @@ public:
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
// Close context menus on right mouse up not handled by menus.
/*virtual*/ BOOL handleRightMouseUp( S32 x, S32 y, MASK mask );
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
virtual const LLRect getMenuRect() const { return getLocalRect(); }
virtual BOOL hasVisibleMenu() const;
LLView*const getVisibleMenu() const;
virtual BOOL hasVisibleMenu() const {return getVisibleMenu() != NULL;}
static void setActivatedItem(LLMenuItemGL* item);
// Need to detect if mouse-up after context menu spawn has moved.
// If not, need to keep the menu up.
static LLCoordGL sContextMenuSpawnPos;
private:
static LLHandle<LLView> sItemLastSelectedHandle;
static LLFrameTimer sItemActivationTimer;
@@ -805,7 +870,7 @@ private:
class LLMenuItemTearOffGL : public LLMenuItemGL
{
public:
LLMenuItemTearOffGL( LLHandle<LLFloater> parent_floater_handle = LLHandle<LLFloater>());
LLMenuItemTearOffGL();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual std::string getType() const { return "tearoff_menu"; }
@@ -814,8 +879,7 @@ public:
virtual void draw(void);
virtual U32 getNominalHeight() const;
private:
LLHandle<LLFloater> mParentHandle;
LLFloater* getParentFloater();
};

View File

@@ -127,7 +127,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const std::string& name, const LLRect& rect
&LLLineEditor::prevalidateFloat );
mEditor->setFollowsLeft();
mEditor->setFollowsBottom();
mEditor->setFocusReceivedCallback( &LLMultiSliderCtrl::onEditorGainFocus, this );
mEditor->setFocusReceivedCallback( boost::bind(&LLMultiSliderCtrl::onFocusReceived, this) );
mEditor->setIgnoreTab(TRUE);
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
@@ -151,16 +151,6 @@ LLMultiSliderCtrl::~LLMultiSliderCtrl()
// Children all cleaned up by default view destructor.
}
// static
void LLMultiSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
LLMultiSliderCtrl* self = (LLMultiSliderCtrl*) userdata;
llassert( caller == self->mEditor );
self->onFocusReceived();
}
void LLMultiSliderCtrl::setValue(const LLSD& value)
{
mMultiSlider->setValue(value);

View File

@@ -126,7 +126,6 @@ public:
static void onSliderCommit(LLUICtrl* caller, void* userdata);
static void onEditorCommit(LLUICtrl* ctrl, void* userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
private:

View File

@@ -79,7 +79,6 @@ void LLPanel::init()
mBorder = NULL;
mDefaultBtn = NULL;
setIsChrome(FALSE); //is this a decorator to a live window or a form?
mLastTabGroup = 0;
mPanelHandle.bind(this);
setTabStop(FALSE);
@@ -269,20 +268,6 @@ void LLPanel::setDefaultBtn(const std::string& id)
}
}
void LLPanel::addCtrl( LLUICtrl* ctrl, S32 tab_group)
{
mLastTabGroup = tab_group;
LLView::addCtrl(ctrl, tab_group);
}
void LLPanel::addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group)
{
mLastTabGroup = tab_group;
LLView::addCtrlAtEnd(ctrl, tab_group);
}
BOOL LLPanel::handleKeyHere( KEY key, MASK mask )
{
BOOL handled = FALSE;
@@ -760,16 +745,6 @@ BOOL LLPanel::childHasFocus(const std::string& id)
}
}
void LLPanel::childSetFocusChangedCallback(const std::string& id, void (*cb)(LLFocusableElement*, void*), void* user_data)
{
LLUICtrl* child = getChild<LLUICtrl>(id, true);
if (child)
{
child->setFocusChangedCallback(cb, user_data);
}
}
void LLPanel::childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void *userdata )
{
LLUICtrl* child = getChild<LLUICtrl>(id, true);
@@ -1199,9 +1174,13 @@ void LLLayoutStack::draw()
}
}
void LLLayoutStack::removeCtrl(LLUICtrl* ctrl)
void LLLayoutStack::removeChild(LLView* ctrl)
{
LLEmbeddedPanel* embedded_panelp = findEmbeddedPanel((LLPanel*)ctrl);
LLView::removeChild(ctrl);
LLPanel* panel = dynamic_cast<LLPanel*>(ctrl);
if(!panel)
return;
LLEmbeddedPanel* embedded_panelp = findEmbeddedPanel(panel);
if (embedded_panelp)
{
@@ -1210,10 +1189,8 @@ void LLLayoutStack::removeCtrl(LLUICtrl* ctrl)
}
// need to update resizebars
calcMinExtents();
LLView::removeCtrl(ctrl);
}
LLXMLNodePtr LLLayoutStack::getXML(bool save_children) const

View File

@@ -138,8 +138,6 @@ public:
LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
S32 getLastTabGroup() const { return mLastTabGroup; }
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
@@ -170,7 +168,6 @@ public:
// LLUICtrl
void childSetFocus(const std::string& id, BOOL focus = TRUE);
BOOL childHasFocus(const std::string& id);
void childSetFocusChangedCallback(const std::string& id, void (*cb)(LLFocusableElement*, void*), void* user_data = NULL);
void childSetCommitCallback(const std::string& id, void (*cb)(LLUICtrl*, void*), void* userdata = NULL );
void childSetDoubleClickCallback(const std::string& id, void (*cb)(void*), void* userdata = NULL );
@@ -236,10 +233,6 @@ private:
// common construction logic
void init();
// From LLView
virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group );
virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
// Unified error reporting for the child* functions
typedef std::set<std::string> expected_members_list_t;
mutable expected_members_list_t mExpectedMembers;
@@ -254,7 +247,6 @@ private:
LLViewBorder* mBorder;
LLButton* mDefaultBtn;
std::string mLabel;
S32 mLastTabGroup;
LLRootHandle<LLPanel> mPanelHandle;
typedef std::map<std::string, std::string> ui_string_map_t;
@@ -279,7 +271,7 @@ public:
/*virtual*/ void draw();
/*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ void removeCtrl(LLUICtrl* ctrl);
/*virtual*/ void removeChild(LLView* ctrl);
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);

View File

@@ -185,7 +185,8 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if (mSnappingEnabled)
{
static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
//static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
switch( mSide )
{
case LEFT:

View File

@@ -46,7 +46,7 @@ const S32 RESIZE_BORDER_WIDTH = 3;
LLResizeHandle::LLResizeHandle( const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner )
:
LLView( name, rect, TRUE ),
LLView( name, rect, FALSE ),
mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ),
@@ -205,7 +205,8 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
LLView* snap_view = NULL;
LLView* test_view = NULL;
static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
//static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
// now do snapping
switch(mCorner)
{

View File

@@ -73,7 +73,8 @@ LLScrollbar::LLScrollbar(
mHighlightColor ( LLUI::sColorsGroup->getColor("DefaultHighlightLight") ),
mShadowColor ( LLUI::sColorsGroup->getColor("DefaultShadowLight") ),
mOnScrollEndCallback( NULL ),
mOnScrollEndData( NULL )
mOnScrollEndData( NULL ),
mThickness( SCROLLBAR_SIZE )
{
//llassert( 0 <= mDocSize );
//llassert( 0 <= mDocPos && mDocPos <= mDocSize );
@@ -92,22 +93,22 @@ LLScrollbar::LLScrollbar(
if( LLScrollbar::VERTICAL == mOrientation )
{
line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), SCROLLBAR_SIZE, SCROLLBAR_SIZE );
line_up_rect.setLeftTopAndSize( 0, getRect().getHeight(), mThickness, mThickness );
line_up_img="UIImgBtnScrollUpOutUUID";
line_up_selected_img="UIImgBtnScrollUpInUUID";
line_down_rect.setOriginAndSize( 0, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
line_down_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
line_down_img="UIImgBtnScrollDownOutUUID";
line_down_selected_img="UIImgBtnScrollDownInUUID";
}
else
{
// Horizontal
line_up_rect.setOriginAndSize( 0, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
line_up_rect.setOriginAndSize( 0, 0, mThickness, mThickness );
line_up_img="UIImgBtnScrollLeftOutUUID";
line_up_selected_img="UIImgBtnScrollLeftInUUID";
line_down_rect.setOriginAndSize( getRect().getWidth() - SCROLLBAR_SIZE, 0, SCROLLBAR_SIZE, SCROLLBAR_SIZE );
line_down_rect.setOriginAndSize( getRect().getWidth() - mThickness, 0, mThickness, mThickness );
line_down_img="UIImgBtnScrollRightOutUUID";
line_down_selected_img="UIImgBtnScrollRightInUUID";
}
@@ -126,7 +127,7 @@ LLScrollbar::LLScrollbar(
line_up_btn->setFollowsLeft();
line_up_btn->setFollowsBottom();
}
line_up_btn->setHeldDownCallback( &LLScrollbar::onLineUpBtnPressed );
line_up_btn->setHeldDownCallback( boost::bind(&LLScrollbar::onLineUpBtnPressed, (void*)this) );
line_up_btn->setTabStop(FALSE);
line_up_btn->setScaleImage(TRUE);
@@ -137,7 +138,7 @@ LLScrollbar::LLScrollbar(
&LLScrollbar::onLineDownBtnPressed, this, LLFontGL::getFontSansSerif() );
line_down_btn->setFollowsRight();
line_down_btn->setFollowsBottom();
line_down_btn->setHeldDownCallback( &LLScrollbar::onLineDownBtnPressed );
line_down_btn->setHeldDownCallback( boost::bind(&LLScrollbar::onLineDownBtnPressed, this) );
line_down_btn->setTabStop(FALSE);
line_down_btn->setScaleImage(TRUE);
addChild(line_down_btn);
@@ -158,7 +159,8 @@ void LLScrollbar::setDocParams( S32 size, S32 pos )
updateThumbRect();
}
void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
// returns true if document position really changed
bool LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
{
pos = llclamp(pos, 0, getDocPosMax());
if (pos != mDocPos)
@@ -175,7 +177,9 @@ void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
{
updateThumbRect();
}
return true;
}
return false;
}
void LLScrollbar::setDocSize(S32 size)
@@ -221,7 +225,7 @@ void LLScrollbar::updateThumbRect()
const S32 THUMB_MIN_LENGTH = 16;
S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight();
S32 thumb_bg_length = llmax(0, window_length - 2 * SCROLLBAR_SIZE);
S32 thumb_bg_length = llmax(0, window_length - 2 * mThickness);
S32 visible_lines = llmin( mDocSize, mPageSize );
S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length;
@@ -229,24 +233,24 @@ void LLScrollbar::updateThumbRect()
if( mOrientation == LLScrollbar::VERTICAL )
{
S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE;
S32 thumb_start_min = SCROLLBAR_SIZE + THUMB_MIN_LENGTH;
S32 thumb_start_max = thumb_bg_length + mThickness;
S32 thumb_start_min = mThickness + THUMB_MIN_LENGTH;
S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max;
mThumbRect.mLeft = 0;
mThumbRect.mTop = thumb_start;
mThumbRect.mRight = SCROLLBAR_SIZE;
mThumbRect.mRight = mThickness;
mThumbRect.mBottom = thumb_start - thumb_length;
}
else
{
// Horizontal
S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE - thumb_length;
S32 thumb_start_min = SCROLLBAR_SIZE;
S32 thumb_start_max = thumb_bg_length + mThickness - thumb_length;
S32 thumb_start_min = mThickness;
S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min;
mThumbRect.mLeft = thumb_start;
mThumbRect.mTop = SCROLLBAR_SIZE;
mThumbRect.mTop = mThickness;
mThumbRect.mRight = thumb_start + thumb_length;
mThumbRect.mBottom = 0;
}
@@ -318,21 +322,21 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
// S32 old_pos = mThumbRect.mTop;
S32 delta_pixels = y - mDragStartY;
if( mOrigRect.mBottom + delta_pixels < SCROLLBAR_SIZE )
if( mOrigRect.mBottom + delta_pixels < mThickness )
{
delta_pixels = SCROLLBAR_SIZE - mOrigRect.mBottom - 1;
delta_pixels = mThickness - mOrigRect.mBottom - 1;
}
else
if( mOrigRect.mTop + delta_pixels > height - SCROLLBAR_SIZE )
if( mOrigRect.mTop + delta_pixels > height - mThickness )
{
delta_pixels = height - SCROLLBAR_SIZE - mOrigRect.mTop + 1;
delta_pixels = height - mThickness - mOrigRect.mTop + 1;
}
mThumbRect.mTop = mOrigRect.mTop + delta_pixels;
mThumbRect.mBottom = mOrigRect.mBottom + delta_pixels;
S32 thumb_length = mThumbRect.getHeight();
S32 thumb_track_length = height - 2 * SCROLLBAR_SIZE;
S32 thumb_track_length = height - 2 * mThickness;
if( delta_pixels != mLastDelta || mDocChanged)
@@ -343,7 +347,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
{
S32 variable_lines = getDocPosMax();
S32 pos = mThumbRect.mTop;
F32 ratio = F32(pos - SCROLLBAR_SIZE - thumb_length) / usable_track_length;
F32 ratio = F32(pos - mThickness - thumb_length) / usable_track_length;
S32 new_pos = llclamp( S32(variable_lines - ratio * variable_lines + 0.5f), 0, variable_lines );
// Note: we do not call updateThumbRect() here. Instead we let the thumb and the document go slightly
@@ -362,21 +366,21 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
S32 delta_pixels = x - mDragStartX;
if( mOrigRect.mLeft + delta_pixels < SCROLLBAR_SIZE )
if( mOrigRect.mLeft + delta_pixels < mThickness )
{
delta_pixels = SCROLLBAR_SIZE - mOrigRect.mLeft - 1;
delta_pixels = mThickness - mOrigRect.mLeft - 1;
}
else
if( mOrigRect.mRight + delta_pixels > width - SCROLLBAR_SIZE )
if( mOrigRect.mRight + delta_pixels > width - mThickness )
{
delta_pixels = width - SCROLLBAR_SIZE - mOrigRect.mRight + 1;
delta_pixels = width - mThickness - mOrigRect.mRight + 1;
}
mThumbRect.mLeft = mOrigRect.mLeft + delta_pixels;
mThumbRect.mRight = mOrigRect.mRight + delta_pixels;
S32 thumb_length = mThumbRect.getWidth();
S32 thumb_track_length = width - 2 * SCROLLBAR_SIZE;
S32 thumb_track_length = width - 2 * mThickness;
if( delta_pixels != mLastDelta || mDocChanged)
{
@@ -386,7 +390,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
{
S32 variable_lines = getDocPosMax();
S32 pos = mThumbRect.mLeft;
F32 ratio = F32(pos - SCROLLBAR_SIZE) / usable_track_length;
F32 ratio = F32(pos - mThickness) / usable_track_length;
S32 new_pos = llclamp( S32(ratio * variable_lines + 0.5f), 0, variable_lines);
@@ -405,7 +409,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
}
else
{
handled = childrenHandleMouseUp( x, y, mask ) != NULL;
handled = childrenHandleHover( x, y, mask ) != NULL;
}
// Opaque
@@ -423,8 +427,8 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
changeLine( clicks * mStepSize, TRUE );
return TRUE;
BOOL handled = changeLine( clicks * mStepSize, TRUE );
return handled;
}
BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -475,14 +479,14 @@ void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
if (mOrientation == VERTICAL)
{
up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, mThickness));
up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight());
}
else
{
up_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), up_button->getRect().getHeight());
down_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), down_button->getRect().getHeight());
up_button->reshape(llmin(getRect().getWidth() / 2, mThickness), up_button->getRect().getHeight());
down_button->reshape(llmin(getRect().getWidth() / 2, mThickness), down_button->getRect().getHeight());
down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom);
}
updateThumbRect();
@@ -513,10 +517,10 @@ void LLScrollbar::draw()
if (!rounded_rect_imagep)
{
gl_rect_2d(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0,
mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * SCROLLBAR_SIZE : getRect().getWidth(),
mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0, mTrackColor, TRUE);
gl_rect_2d(mOrientation == HORIZONTAL ? mThickness : 0,
mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(),
mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * mThickness : getRect().getWidth(),
mOrientation == VERTICAL ? mThickness : 0, mTrackColor, TRUE);
gl_rect_2d(mThumbRect, mThumbColor, TRUE);
@@ -560,9 +564,9 @@ void LLScrollbar::draw()
} // end draw
void LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
bool LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
{
setDocPos(mDocPos + delta, update_thumb);
return setDocPos(mDocPos + delta, update_thumb);
}
void LLScrollbar::setValue(const LLSD& value)

View File

@@ -82,7 +82,7 @@ public:
// How many "lines" the "document" has scrolled.
// 0 <= DocPos <= DocSize - DocVisibile
void setDocPos( S32 pos, BOOL update_thumb = TRUE );
bool setDocPos( S32 pos, BOOL update_thumb = TRUE );
S32 getDocPos() const { return mDocPos; }
BOOL isAtBeginning();
@@ -113,7 +113,7 @@ public:
private:
void updateThumbRect();
void changeLine(S32 delta, BOOL update_thumb );
bool changeLine(S32 delta, BOOL update_thumb );
void (*mChangeCallback)( S32 new_pos, LLScrollbar* self, void* userdata );
void* mCallbackUserData;
@@ -142,6 +142,7 @@ private:
void (*mOnScrollEndCallback)(void*);
void *mOnScrollEndData;
S32 mThickness;
};

View File

@@ -69,52 +69,31 @@ LLScrollableContainerView::LLScrollableContainerView( const std::string& name,
BOOL is_opaque,
const LLColor4& bg_color ) :
LLUICtrl( name, rect, FALSE, NULL, NULL ),
mScrolledView( scrolled_view ),
mIsOpaque( is_opaque ),
mBackgroundColor( bg_color ),
mReserveScrollCorner( FALSE ),
mAutoScrolling( FALSE ),
mAutoScrollRate( 0.f )
mAutoScrollRate( 0.f ),
mBackgroundColor( bg_color ),
mIsOpaque( is_opaque ),
mHideScrollbar( FALSE ),
mReserveScrollCorner( FALSE ),
mMinAutoScrollRate( MIN_AUTO_SCROLL_RATE ),
mMaxAutoScrollRate( MAX_AUTO_SCROLL_RATE ),
mScrolledView( scrolled_view )
{
if( mScrolledView )
{
addChild( mScrolledView );
LLView::addChild( mScrolledView );
}
init();
}
// LLUICtrl constructor
LLScrollableContainerView::LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLUICtrl* scrolled_ctrl, BOOL is_opaque,
const LLColor4& bg_color) :
LLUICtrl( name, rect, FALSE, NULL, NULL ),
mScrolledView( scrolled_ctrl ),
mIsOpaque( is_opaque ),
mBackgroundColor( bg_color ),
mReserveScrollCorner( FALSE ),
mAutoScrolling( FALSE ),
mAutoScrollRate( 0.f )
{
if( scrolled_ctrl )
{
addChild( scrolled_ctrl );
}
init();
}
void LLScrollableContainerView::init()
{
S32 scrollbar_size = SCROLLBAR_SIZE;
LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mBorder = new LLViewBorder( std::string("scroll border"), border_rect, LLViewBorder::BEVEL_IN );
addChild( mBorder );
LLView::addChild( mBorder );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mInnerRect.stretch( -mBorder->getBorderWidth() );
mInnerRect.stretch( -getBorderWidth() );
LLRect vertical_scroll_rect = mInnerRect;
vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - SCROLLBAR_SIZE;
vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size;
mScrollbar[VERTICAL] = new LLScrollbar( std::string("scrollable vertical"),
vertical_scroll_rect,
LLScrollbar::VERTICAL,
@@ -123,14 +102,14 @@ void LLScrollableContainerView::init()
mInnerRect.getHeight(),
NULL, this,
VERTICAL_MULTIPLE);
addChild( mScrollbar[VERTICAL] );
LLView::addChild( mScrollbar[VERTICAL] );
mScrollbar[VERTICAL]->setVisible( FALSE );
mScrollbar[VERTICAL]->setFollowsRight();
mScrollbar[VERTICAL]->setFollowsTop();
mScrollbar[VERTICAL]->setFollowsBottom();
LLRect horizontal_scroll_rect = mInnerRect;
horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + SCROLLBAR_SIZE;
horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + scrollbar_size;
mScrollbar[HORIZONTAL] = new LLScrollbar( std::string("scrollable horizontal"),
horizontal_scroll_rect,
LLScrollbar::HORIZONTAL,
@@ -139,7 +118,7 @@ void LLScrollableContainerView::init()
mInnerRect.getWidth(),
NULL, this,
HORIZONTAL_MULTIPLE);
addChild( mScrollbar[HORIZONTAL] );
LLView::addChild( mScrollbar[HORIZONTAL] );
mScrollbar[HORIZONTAL]->setVisible( FALSE );
mScrollbar[HORIZONTAL]->setFollowsLeft();
mScrollbar[HORIZONTAL]->setFollowsRight();
@@ -190,8 +169,8 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
{
LLUICtrl::reshape( width, height, called_from_parent );
mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 );
mInnerRect.stretch( -mBorder->getBorderWidth() );
mInnerRect = getLocalRect();
mInnerRect.stretch( -getBorderWidth() );
if (mScrolledView)
{
@@ -201,22 +180,33 @@ void LLScrollableContainerView::reshape(S32 width, S32 height,
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
mScrollbar[VERTICAL]->setPageSize( visible_height );
mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
mScrollbar[HORIZONTAL]->setPageSize( visible_width );
updateScroll();
}
}
BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
{
// allow scrolled view to handle keystrokes in case it delegated keyboard focus
// to the scroll container.
// NOTE: this should not recurse indefinitely as handleKeyHere
// should not propagate to parent controls, so mScrolledView should *not*
// call LLScrollContainer::handleKeyHere in turn
if (mScrolledView && mScrolledView->handleKeyHere(key, mask))
{
return TRUE;
}
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
{
if( mScrollbar[i]->handleKeyHere(key, mask) )
{
updateScroll();
return TRUE;
}
}
@@ -226,38 +216,37 @@ BOOL LLScrollableContainerView::handleKeyHere(KEY key, MASK mask)
BOOL LLScrollableContainerView::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
for( S32 i = 0; i < SCROLLBAR_COUNT; i++ )
{
// Note: tries vertical and then horizontal
// Give event to my child views - they may have scroll bars
// (Bad UI design, but technically possible.)
if (LLUICtrl::handleScrollWheel(x,y,clicks))
return TRUE;
// When the vertical scrollbar is visible, scroll wheel
// only affects vertical scrolling. It's confusing to have
// scroll wheel perform both vertical and horizontal in a
// single container.
LLScrollbar* vertical = mScrollbar[VERTICAL];
if (vertical->getVisible()
&& vertical->getEnabled())
{
// Pretend the mouse is over the scrollbar
if( mScrollbar[i]->handleScrollWheel( 0, 0, clicks ) )
if (vertical->handleScrollWheel( 0, 0, clicks ) )
{
return TRUE;
updateScroll();
}
// Always eat the event
return TRUE;
}
// Eat scroll wheel event (to avoid scrolling nested containers?)
return TRUE;
}
BOOL LLScrollableContainerView::needsToScroll(S32 x, S32 y, LLScrollableContainerView::SCROLL_ORIENTATION axis) const
{
if(mScrollbar[axis]->getVisible())
LLScrollbar* horizontal = mScrollbar[HORIZONTAL];
// Test enablement and visibility for consistency with
// LLView::childrenHandleScrollWheel().
if (horizontal->getVisible()
&& horizontal->getEnabled()
&& horizontal->handleScrollWheel( 0, 0, clicks ) )
{
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
const S32 AUTOSCROLL_SIZE = 10;
if(mScrollbar[axis]->getVisible())
{
inner_rect_local.mRight -= SCROLLBAR_SIZE;
inner_rect_local.mTop += AUTOSCROLL_SIZE;
inner_rect_local.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
}
if( inner_rect_local.pointInRect( x, y ) && (mScrollbar[axis]->getDocPos() > 0) )
{
return TRUE;
}
updateScroll();
return TRUE;
}
return FALSE;
}
@@ -269,65 +258,10 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
//S32 scrollbar_size = SCROLLBAR_SIZE;
// Scroll folder view if needed. Never accepts a drag or drop.
*accept = ACCEPT_NO;
BOOL handled = FALSE;
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
{
const S32 AUTOSCROLL_SIZE = 10;
S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
if( mScrollbar[HORIZONTAL]->getVisible() )
{
inner_rect_local.mBottom += SCROLLBAR_SIZE;
}
if( mScrollbar[VERTICAL]->getVisible() )
{
inner_rect_local.mRight -= SCROLLBAR_SIZE;
}
if( mScrollbar[HORIZONTAL]->getVisible() )
{
LLRect left_scroll_rect = inner_rect_local;
left_scroll_rect.mRight = AUTOSCROLL_SIZE;
if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
LLRect right_scroll_rect = inner_rect_local;
right_scroll_rect.mLeft = inner_rect_local.mRight - AUTOSCROLL_SIZE;
if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
}
if( mScrollbar[VERTICAL]->getVisible() )
{
LLRect bottom_scroll_rect = inner_rect_local;
bottom_scroll_rect.mTop = AUTOSCROLL_SIZE + bottom_scroll_rect.mBottom;
if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
LLRect top_scroll_rect = inner_rect_local;
top_scroll_rect.mBottom = inner_rect_local.mTop - AUTOSCROLL_SIZE;
if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
handled = TRUE;
}
}
}
BOOL handled = autoScroll(x, y);
if( !handled )
{
@@ -338,6 +272,78 @@ BOOL LLScrollableContainerView::handleDragAndDrop(S32 x, S32 y, MASK mask,
return TRUE;
}
bool LLScrollableContainerView::autoScroll(S32 x, S32 y)
{
S32 scrollbar_size = SCROLLBAR_SIZE;
bool scrolling = false;
if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
{
LLRect screen_local_extents;
screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents);
LLRect inner_rect_local( 0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0 );
if( mScrollbar[HORIZONTAL]->getVisible() )
{
inner_rect_local.mBottom += scrollbar_size;
}
if( mScrollbar[VERTICAL]->getVisible() )
{
inner_rect_local.mRight -= scrollbar_size;
}
// clip rect against root view
inner_rect_local.intersectWith(screen_local_extents);
S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
// autoscroll region should take up no more than one third of visible scroller area
S32 auto_scroll_region_width = llmin(inner_rect_local.getWidth() / 3, 10);
S32 auto_scroll_region_height = llmin(inner_rect_local.getHeight() / 3, 10);
if( mScrollbar[HORIZONTAL]->getVisible() )
{
LLRect left_scroll_rect = screen_local_extents;
left_scroll_rect.mRight = inner_rect_local.mLeft + auto_scroll_region_width;
if( left_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() > 0) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
LLRect right_scroll_rect = screen_local_extents;
right_scroll_rect.mLeft = inner_rect_local.mRight - auto_scroll_region_width;
if( right_scroll_rect.pointInRect( x, y ) && (mScrollbar[HORIZONTAL]->getDocPos() < mScrollbar[HORIZONTAL]->getDocPosMax()) )
{
mScrollbar[HORIZONTAL]->setDocPos( mScrollbar[HORIZONTAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
}
if( mScrollbar[VERTICAL]->getVisible() )
{
LLRect bottom_scroll_rect = screen_local_extents;
bottom_scroll_rect.mTop = inner_rect_local.mBottom + auto_scroll_region_height;
if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() < mScrollbar[VERTICAL]->getDocPosMax()) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() + auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
LLRect top_scroll_rect = screen_local_extents;
top_scroll_rect.mBottom = inner_rect_local.mTop - auto_scroll_region_height;
if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar[VERTICAL]->getDocPos() > 0) )
{
mScrollbar[VERTICAL]->setDocPos( mScrollbar[VERTICAL]->getDocPos() - auto_scroll_speed );
mAutoScrolling = TRUE;
scrolling = true;
}
}
}
return scrolling;
}
BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect)
{
@@ -368,42 +374,44 @@ BOOL LLScrollableContainerView::handleToolTip(S32 x, S32 y, std::string& msg, LL
void LLScrollableContainerView::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{
const LLRect& rect = mScrolledView->getRect();
calcVisibleSize(rect, visible_width, visible_height, show_h_scrollbar, show_v_scrollbar);
}
void LLScrollableContainerView::calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
{
const LLRect& doc_rect = getScrolledViewRect();
S32 scrollbar_size = SCROLLBAR_SIZE;
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 = getBorderWidth();
*visible_width = getRect().getWidth() - 2 * border_width;
*visible_height = getRect().getHeight() - 2 * 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;
*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;
}
}
}
}
void LLScrollableContainerView::draw()
{
S32 scrollbar_size = SCROLLBAR_SIZE;
if (mAutoScrolling)
{
// add acceleration to autoscroll
@@ -411,76 +419,79 @@ void LLScrollableContainerView::draw()
}
else
{
// reset to minimum
mAutoScrollRate = MIN_AUTO_SCROLL_RATE;
// reset to minimum for next time
mAutoScrollRate = mMinAutoScrollRate;
}
// clear this flag to be set on next call to handleDragAndDrop
// clear this flag to be set on next call to autoScroll
mAutoScrolling = FALSE;
// auto-focus when scrollbar active
// this allows us to capture user intent (i.e. stop automatically scrolling the view/etc)
if (!gFocusMgr.childHasKeyboardFocus(this) &&
(mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
if (!hasFocus()
&& (mScrollbar[VERTICAL]->hasMouseCapture() || mScrollbar[HORIZONTAL]->hasMouseCapture()))
{
focusFirstItem();
}
// Draw background
if( mIsOpaque )
if (getRect().isValid())
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4fv( mBackgroundColor.mV );
gl_rect_2d( mInnerRect );
}
// Draw background
if( mIsOpaque )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.color4fv( mBackgroundColor.mV );
gl_rect_2d( mInnerRect );
}
// Draw mScrolledViews and update scroll bars.
// get a scissor region ready, and draw the scrolling view. The
// scissor region ensures that we don't draw outside of the bounds
// of the rectangle.
if( mScrolledView )
{
updateScroll();
// Draw the scrolled area.
// Draw mScrolledViews and update scroll bars.
// get a scissor region ready, and draw the scrolling view. The
// scissor region ensures that we don't draw outside of the bounds
// of the rectangle.
if( mScrolledView )
{
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( mScrolledView->getRect(), &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
updateScroll();
LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0) + visible_height,
visible_width,
mInnerRect.mBottom + (show_h_scrollbar ? SCROLLBAR_SIZE : 0)
));
drawChild(mScrolledView);
// Draw the scrolled area.
{
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height,
mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0),
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0)
));
drawChild(mScrolledView);
}
}
}
// Highlight border if a child of this container has keyboard focus
if( mBorder->getVisible() )
{
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
}
// Highlight border if a child of this container has keyboard focus
if( mBorder->getVisible() )
{
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
}
// Draw all children except mScrolledView
// Note: scrollbars have been adjusted by above drawing code
for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
child_iter != getChildList()->rend(); ++child_iter)
{
LLView *viewp = *child_iter;
if( sDebugRects )
// Draw all children except mScrolledView
// Note: scrollbars have been adjusted by above drawing code
for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
child_iter != getChildList()->rend(); ++child_iter)
{
sDepth++;
}
if( (viewp != mScrolledView) && viewp->getVisible() )
{
drawChild(viewp);
}
if( sDebugRects )
{
sDepth--;
LLView *viewp = *child_iter;
if( sDebugRects )
{
sDepth++;
}
if( (viewp != mScrolledView) && viewp->getVisible() )
{
drawChild(viewp);
}
if( sDebugRects )
{
sDepth--;
}
}
}
@@ -491,8 +502,30 @@ void LLScrollableContainerView::draw()
} // end draw
bool LLScrollableContainerView::addChild(LLView* view, S32 tab_group)
{
if (!mScrolledView)
{
// Use the first panel or container as the scrollable view (bit of a hack)
mScrolledView = view;
}
bool ret_val = LLView::addChild(view, tab_group);
//bring the scrollbars to the front
sendChildToFront( mScrollbar[HORIZONTAL] );
sendChildToFront( mScrollbar[VERTICAL] );
return ret_val;
}
void LLScrollableContainerView::updateScroll()
{
if (!mScrolledView)
{
return;
}
S32 scrollbar_size = SCROLLBAR_SIZE;
LLRect doc_rect = mScrolledView->getRect();
S32 doc_width = doc_rect.getWidth();
S32 doc_height = doc_rect.getHeight();
@@ -500,9 +533,9 @@ void LLScrollableContainerView::updateScroll()
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( doc_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
S32 border_width = mBorder->getBorderWidth();
S32 border_width = getBorderWidth();
if( show_v_scrollbar )
{
if( doc_rect.mTop < getRect().getHeight() - border_width )
@@ -516,15 +549,15 @@ void LLScrollableContainerView::updateScroll()
S32 v_scrollbar_height = visible_height;
if( !show_h_scrollbar && mReserveScrollCorner )
{
v_scrollbar_height -= SCROLLBAR_SIZE;
v_scrollbar_height -= scrollbar_size;
}
mScrollbar[VERTICAL]->reshape( SCROLLBAR_SIZE, v_scrollbar_height, TRUE );
mScrollbar[VERTICAL]->reshape( scrollbar_size, v_scrollbar_height, TRUE );
// Make room for the horizontal scrollbar (or not)
S32 v_scrollbar_offset = 0;
if( show_h_scrollbar || mReserveScrollCorner )
{
v_scrollbar_offset = SCROLLBAR_SIZE;
v_scrollbar_offset = scrollbar_size;
}
LLRect r = mScrollbar[VERTICAL]->getRect();
r.translate( 0, mInnerRect.mBottom - r.mBottom + v_scrollbar_offset );
@@ -554,9 +587,9 @@ void LLScrollableContainerView::updateScroll()
S32 h_scrollbar_width = visible_width;
if( !show_v_scrollbar && mReserveScrollCorner )
{
h_scrollbar_width -= SCROLLBAR_SIZE;
h_scrollbar_width -= scrollbar_size;
}
mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, SCROLLBAR_SIZE, TRUE );
mScrollbar[HORIZONTAL]->reshape( h_scrollbar_width, scrollbar_size, TRUE );
}
else
{
@@ -576,101 +609,115 @@ void LLScrollableContainerView::updateScroll()
void LLScrollableContainerView::setBorderVisible(BOOL b)
{
mBorder->setVisible( b );
// Recompute inner rect, as border visibility changes it
mInnerRect = getLocalRect();
mInnerRect.stretch( -getBorderWidth() );
}
// Scroll so that as much of rect as possible is showing (where rect is defined in the space of scroller view, not scrolled)
void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLCoordGL& desired_offset)
LLRect LLScrollableContainerView::getVisibleContentRect()
{
updateScroll();
LLRect visible_rect = getContentWindowRect();
LLRect contents_rect = mScrolledView->getRect();
visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom);
return visible_rect;
}
LLRect LLScrollableContainerView::getContentWindowRect()
{
updateScroll();
LLRect scroller_view_rect;
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_h_scrollbar = FALSE;
BOOL show_v_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
S32 border_width = getBorderWidth();
scroller_view_rect.setOriginAndSize(border_width,
show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width,
visible_width,
visible_height);
return scroller_view_rect;
}
// rect is in document coordinates, constraint is in display coordinates relative to content window rect
void LLScrollableContainerView::scrollToShowRect(const LLRect& rect, const LLRect& constraint)
{
if (!mScrolledView)
{
llwarns << "LLScrollableContainerView::scrollToShowRect with no view!" << llendl;
llwarns << "LLScrollContainer::scrollToShowRect with no view!" << llendl;
return;
}
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
const LLRect& scrolled_rect = mScrolledView->getRect();
calcVisibleSize( scrolled_rect, &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
LLRect content_window_rect = getContentWindowRect();
// get document rect
LLRect scrolled_rect = mScrolledView->getRect();
// can't be so far left that right side of rect goes off screen, or so far right that left side does
S32 horiz_offset = llclamp(desired_offset.mX, llmin(0, -visible_width + rect.getWidth()), 0);
// can't be so high that bottom of rect goes off screen, or so low that top does
S32 vert_offset = llclamp(desired_offset.mY, 0, llmax(0, visible_height - rect.getHeight()));
// shrink target rect to fit within constraint region, biasing towards top left
LLRect rect_to_constrain = rect;
rect_to_constrain.mBottom = llmax(rect_to_constrain.mBottom, rect_to_constrain.mTop - constraint.getHeight());
rect_to_constrain.mRight = llmin(rect_to_constrain.mRight, rect_to_constrain.mLeft + constraint.getWidth());
// Vertical
// 1. First make sure the top is visible
// 2. Then, if possible without hiding the top, make the bottom visible.
S32 vert_pos = mScrollbar[VERTICAL]->getDocPos();
// calculate allowable positions for scroller window in document coordinates
LLRect allowable_scroll_rect(rect_to_constrain.mRight - constraint.mRight,
rect_to_constrain.mBottom - constraint.mBottom,
rect_to_constrain.mLeft - constraint.mLeft,
rect_to_constrain.mTop - constraint.mTop);
// find scrollbar position to get top of rect on screen (scrolling up)
S32 top_offset = scrolled_rect.mTop - rect.mTop - vert_offset;
// find scrollbar position to get bottom of rect on screen (scrolling down)
S32 bottom_offset = vert_offset == 0 ? scrolled_rect.mTop - rect.mBottom - visible_height : top_offset;
// scroll up far enough to see top or scroll down just enough if item is bigger than visual area
if( vert_pos >= top_offset || visible_height < rect.getHeight())
{
vert_pos = top_offset;
}
// else scroll down far enough to see bottom
else
if( vert_pos <= bottom_offset )
{
vert_pos = bottom_offset;
}
// translate from allowable region for lower left corner to upper left corner
allowable_scroll_rect.translate(0, content_window_rect.getHeight());
S32 vert_pos = llclamp(mScrollbar[VERTICAL]->getDocPos(),
mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mTop, // min vertical scroll
mScrollbar[VERTICAL]->getDocSize() - allowable_scroll_rect.mBottom); // max vertical scroll
mScrollbar[VERTICAL]->setDocSize( scrolled_rect.getHeight() );
mScrollbar[VERTICAL]->setPageSize( visible_height );
mScrollbar[VERTICAL]->setPageSize( content_window_rect.getHeight() );
mScrollbar[VERTICAL]->setDocPos( vert_pos );
// Horizontal
// 1. First make sure left side is visible
// 2. Then, if possible without hiding the left side, make the right side visible.
S32 horiz_pos = mScrollbar[HORIZONTAL]->getDocPos();
S32 left_offset = rect.mLeft - scrolled_rect.mLeft + horiz_offset;
S32 right_offset = horiz_offset == 0 ? rect.mRight - scrolled_rect.mLeft - visible_width : left_offset;
S32 horizontal_pos = llclamp(mScrollbar[HORIZONTAL]->getDocPos(),
allowable_scroll_rect.mLeft,
allowable_scroll_rect.mRight);
if( horiz_pos >= left_offset || visible_width < rect.getWidth() )
{
horiz_pos = left_offset;
}
else if( horiz_pos <= right_offset )
{
horiz_pos = right_offset;
}
mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
mScrollbar[HORIZONTAL]->setPageSize( visible_width );
mScrollbar[HORIZONTAL]->setDocPos( horiz_pos );
mScrollbar[HORIZONTAL]->setPageSize( content_window_rect.getWidth() );
mScrollbar[HORIZONTAL]->setDocPos( horizontal_pos );
// propagate scroll to document
updateScroll();
// In case we are in accordion tab notify parent to show selected rectangle
LLRect screen_rc;
localRectToScreen(rect_to_constrain, &screen_rc);
notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
}
void LLScrollableContainerView::pageUp(S32 overlap)
{
mScrollbar[VERTICAL]->pageUp(overlap);
updateScroll();
}
void LLScrollableContainerView::pageDown(S32 overlap)
{
mScrollbar[VERTICAL]->pageDown(overlap);
updateScroll();
}
void LLScrollableContainerView::goToTop()
{
mScrollbar[VERTICAL]->setDocPos(0);
updateScroll();
}
void LLScrollableContainerView::goToBottom()
{
mScrollbar[VERTICAL]->setDocPos(mScrollbar[VERTICAL]->getDocSize());
updateScroll();
}
S32 LLScrollableContainerView::getBorderWidth() const
{
if (mBorder)
if (mBorder && mBorder->getVisible())
{
return mBorder->getBorderWidth();
}

View File

@@ -63,30 +63,29 @@ public:
LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLView* scrolled_view, BOOL is_opaque = FALSE,
const LLColor4& bg_color = LLColor4(0,0,0,0) );
LLScrollableContainerView( const std::string& name, const LLRect& rect,
LLUICtrl* scrolled_ctrl, BOOL is_opaque = FALSE,
const LLColor4& bg_color = LLColor4(0,0,0,0) );
virtual ~LLScrollableContainerView( void );
void setScrolledView(LLView* view) { mScrolledView = view; }
virtual void setValue(const LLSD& value) { mInnerRect.setValue(value); }
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
void calcVisibleSize( const LLRect& doc_rect, S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
void setBorderVisible( BOOL b );
void scrollToShowRect( const LLRect& rect, const LLCoordGL& desired_offset );
void scrollToShowRect( const LLRect& rect, const LLRect& constraint);
void scrollToShowRect( const LLRect& rect) { scrollToShowRect(rect, LLRect(0, mInnerRect.getHeight(), mInnerRect.getWidth(), 0)); }
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
const LLRect& getScrolledViewRect() const { return mScrolledView->getRect(); }
LLRect getVisibleContentRect();
LLRect getContentWindowRect();
const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
void pageUp(S32 overlap = 0);
void pageDown(S32 overlap = 0);
void goToTop();
void goToBottom();
bool isAtTop() { return mScrollbar[VERTICAL]->isAtBeginning(); }
bool isAtBottom() { return mScrollbar[VERTICAL]->isAtEnd(); }
S32 getBorderWidth() const;
BOOL needsToScroll(S32 x, S32 y, SCROLL_ORIENTATION axis) const;
// LLView functionality
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual BOOL handleKeyHere(KEY key, MASK mask);
@@ -99,8 +98,10 @@ public:
virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect);
virtual void draw();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
virtual bool addChild(LLView* view, S32 tab_group = 0);
bool autoScroll(S32 x, S32 y);
virtual LLXMLNodePtr getXML(bool save_children) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
private:
@@ -110,6 +111,9 @@ private:
virtual void scrollHorizontal( S32 new_pos );
virtual void scrollVertical( S32 new_pos );
void updateScroll();
public:
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
private:
LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
LLView* mScrolledView;
@@ -121,6 +125,9 @@ private:
BOOL mReserveScrollCorner;
BOOL mAutoScrolling;
F32 mAutoScrollRate;
F32 mMinAutoScrollRate;
F32 mMaxAutoScrollRate;
bool mHideScrollbar;
};

View File

@@ -52,7 +52,7 @@ void LLScrollingPanelList::clearPanels()
void LLScrollingPanelList::addPanel( LLScrollingPanel* panel )
{
addChildAtEnd( panel );
addChildInBack( panel );
mPanelList.push_front( panel );
const S32 GAP_BETWEEN_PANELS = 6;

View File

@@ -117,7 +117,11 @@ LLScrollListIcon::LLScrollListIcon(LLUIImagePtr icon, S32 width)
LLScrollListIcon::LLScrollListIcon(const LLSD& value, S32 width)
: LLScrollListCell(width),
mColor(LLColor4::white)
// <edit>
mCallback(NULL),
mUserData(NULL),
// </edit>
mColor(LLColor4::white)
{
setValue(value);
}
@@ -637,6 +641,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
: LLUICtrl(name, rect, TRUE, commit_callback, callback_user_data),
mLineHeight(0),
mScrollLines(0),
mMouseWheelOpaque(true),
mPageLines(0),
mHeadingHeight(20),
mMaxSelectable(0),
@@ -745,11 +750,6 @@ S32 LLScrollListCtrl::getSearchColumn()
LLScrollListCtrl::~LLScrollListCtrl()
{
std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
if( gEditMenuHandler == this )
{
gEditMenuHandler = NULL;
}
}
@@ -1951,6 +1951,12 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
BOOL handled = FALSE;
// Pretend the mouse is over the scrollbar
handled = mScrollbar->handleScrollWheel( 0, 0, clicks );
if (mMouseWheelOpaque)
{
return TRUE;
}
return handled;
}
@@ -2129,6 +2135,8 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
mSelectionChanged = FALSE;
handleClick(x, y, mask);
setFocus(TRUE);
}
return TRUE;
@@ -2843,6 +2851,8 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
node->createChild("draw_stripes", TRUE)->setBoolValue(mDrawStripes);
node->createChild("column_padding", TRUE)->setIntValue(mColumnPadding);
node->createChild("mouse_wheel_opaque", TRUE)->setBoolValue(mMouseWheelOpaque);
addColorXML(node, mBgWriteableColor, "bg_writeable_color", "ScrollBgWriteableColor");
addColorXML(node, mBgReadOnlyColor, "bg_read_only_color", "ScrollBgReadOnlyColor");
@@ -2970,6 +2980,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
BOOL sort_ascending = TRUE;
node->getAttributeBOOL("sort_ascending", sort_ascending);
BOOL mouse_wheel_opaque = TRUE;
node->getAttributeBOOL("mouse_wheel_opaque", mouse_wheel_opaque);
LLUICtrlCallback callback = NULL;
@@ -2994,6 +3007,8 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
scroll_list->initFromXML(node, parent);
scroll_list->setSearchColumn(search_column);
scroll_list->mMouseWheelOpaque = mouse_wheel_opaque;
LLSD columns;
S32 index = 0;
@@ -3684,9 +3699,9 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS
mButton->setTabStop(FALSE);
// require at least two frames between mouse down and mouse up event to capture intentional "hold" not just bad framerate
mButton->setHeldDownDelay(LLUI::sConfigGroup->getF32("ColumnHeaderDropDownDelay"), 2);
mButton->setHeldDownCallback(onHeldDown);
mButton->setClickedCallback(onClick);
mButton->setMouseDownCallback(onMouseDown);
mButton->setHeldDownCallback(boost::bind(&LLColumnHeader::onHeldDown, this));
mButton->setClickedCallback(boost::bind(&LLColumnHeader::onClick, this));
mButton->setMouseDownCallback(boost::bind(&LLColumnHeader::onMouseDown, this));
mButton->setCallbackUserData(this);
mButton->setToolTip(label);
@@ -3848,8 +3863,8 @@ void LLColumnHeader::setImage(const std::string &image_name)
{
if (mButton)
{
mButton->setImageSelected(image_name);
mButton->setImageUnselected(image_name);
mButton->setImageSelected(LLUI::getUIImage(image_name));
mButton->setImageUnselected(LLUI::getUIImage(image_name));
}
}
@@ -3885,6 +3900,8 @@ void LLColumnHeader::onClick(void* user_data)
// propagate new sort order to sort order list
headerp->mList->selectNthItem(column->mParentCtrl->getSortAscending() ? 0 : 1);
headerp->mList->setFocus(TRUE);
}
//static

View File

@@ -671,6 +671,7 @@ private:
BOOL mCommitOnSelectionChange;
BOOL mSelectionChanged;
BOOL mNeedsScroll;
BOOL mMouseWheelOpaque;
BOOL mCanSelect;
BOOL mDisplayColumnHeaders;
BOOL mColumnsDirty;

View File

@@ -121,7 +121,7 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
&LLLineEditor::prevalidateFloat );
mEditor->setFollowsLeft();
mEditor->setFollowsBottom();
mEditor->setFocusReceivedCallback( &LLSliderCtrl::onEditorGainFocus, this );
mEditor->setFocusReceivedCallback( boost::bind(&LLSliderCtrl::onFocusReceived, this) );
mEditor->setIgnoreTab(TRUE);
// don't do this, as selecting the entire text is single clicking in some cases
// and double clicking in others
@@ -140,17 +140,6 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
updateText();
}
// static
void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
LLSliderCtrl* self = (LLSliderCtrl*) userdata;
llassert( caller == self->mEditor );
self->onFocusReceived();
}
void LLSliderCtrl::setValue(F32 v, BOOL from_event)
{
mSlider->setValue( v, from_event );

View File

@@ -117,7 +117,6 @@ public:
static void onSliderCommit(LLUICtrl* caller, void* userdata);
static void onEditorCommit(LLUICtrl* caller, void* userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
private:

View File

@@ -101,7 +101,7 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::
&LLSpinCtrl::onUpBtn, this, LLFontGL::getFontSansSerif() );
mUpBtn->setFollowsLeft();
mUpBtn->setFollowsBottom();
mUpBtn->setHeldDownCallback( &LLSpinCtrl::onUpBtn );
mUpBtn->setHeldDownCallback(boost::bind(&LLSpinCtrl::onUpBtn,this));
mUpBtn->setTabStop(FALSE);
addChild(mUpBtn);
@@ -115,7 +115,7 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::
&LLSpinCtrl::onDownBtn, this, LLFontGL::getFontSansSerif() );
mDownBtn->setFollowsLeft();
mDownBtn->setFollowsBottom();
mDownBtn->setHeldDownCallback( &LLSpinCtrl::onDownBtn );
mDownBtn->setHeldDownCallback(boost::bind(&LLSpinCtrl::onDownBtn,this));
mDownBtn->setTabStop(FALSE);
addChild(mDownBtn);
@@ -126,7 +126,7 @@ LLSpinCtrl::LLSpinCtrl( const std::string& name, const LLRect& rect, const std::
&LLLineEditor::prevalidateASCII );
mEditor->setFollowsLeft();
mEditor->setFollowsBottom();
mEditor->setFocusReceivedCallback( &LLSpinCtrl::onEditorGainFocus, this );
mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onFocusReceived, this) );
//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
// than when it doesn't. Instead, if you always have to double click to select all the text,
// it's easier to understand
@@ -243,15 +243,6 @@ void LLSpinCtrl::onDownBtn( void *userdata )
}
}
// static
void LLSpinCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
LLSpinCtrl* self = (LLSpinCtrl*) userdata;
llassert( caller == self->mEditor );
self->onFocusReceived();
}
void LLSpinCtrl::setValue(const LLSD& value )
{
F32 v = (F32)value.asReal();

View File

@@ -110,7 +110,6 @@ public:
virtual void draw();
static void onEditorCommit(LLUICtrl* caller, void* userdata);
static void onEditorGainFocus(LLFocusableElement* caller, void *userdata);
static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata);
static void onUpBtn(void *userdata);

View File

@@ -803,7 +803,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
LLStringUtil::null,
LLStringUtil::null,
LLStringUtil::null,
&LLTabContainer::onTabBtn, NULL,
NULL, NULL,
font,
trimmed_label, trimmed_label);
btn->setImages(std::string("tab_left.tga"), std::string("tab_left_selected.tga"));
@@ -825,7 +825,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
btn = new LLButton(std::string(child->getName()) + " tab",
btn_rect,
LLStringUtil::null, LLStringUtil::null, LLStringUtil::null,
&LLTabContainer::onTabBtn, NULL, // set userdata below
NULL, NULL, // set userdata below
font,
trimmed_label, trimmed_label );
btn->setVisible( FALSE );
@@ -865,7 +865,7 @@ void LLTabContainer::addTabPanel(LLPanel* child,
if (btn)
{
btn->setSaveToXML(false);
btn->setCallbackUserData( tuple );
btn->setClickedCallback(&LLTabContainer::onTabBtn, tuple);
addChild( btn, 0 );
}
if (child)
@@ -1682,7 +1682,7 @@ void LLTabContainer::initButtons()
mPrevArrowBtn = new LLButton(std::string("Left Arrow"), left_arrow_btn_rect,
out_id, in_id, LLStringUtil::null,
&LLTabContainer::onPrevBtn, this, LLFontGL::getFontSansSerif() );
mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld);
mPrevArrowBtn->setHeldDownCallback(boost::bind(LLTabContainer::onPrevBtnHeld, this));
mPrevArrowBtn->setFollowsLeft();
out_id = "UIImgBtnJumpRightOutUUID";
@@ -1717,12 +1717,12 @@ void LLTabContainer::initButtons()
}
}
mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld);
mPrevArrowBtn->setHeldDownCallback(boost::bind(&LLTabContainer::onPrevBtnHeld, this));
mPrevArrowBtn->setSaveToXML(false);
mPrevArrowBtn->setTabStop(FALSE);
addChild(mPrevArrowBtn);
mNextArrowBtn->setHeldDownCallback(onNextBtnHeld);
mNextArrowBtn->setHeldDownCallback(boost::bind(&LLTabContainer::onNextBtnHeld, this));
mNextArrowBtn->setSaveToXML(false);
mNextArrowBtn->setTabStop(FALSE);
addChild(mNextArrowBtn);

View File

@@ -356,12 +356,12 @@ LLTextEditor::LLTextEditor(
{
menu = new LLMenuGL(LLStringUtil::null);
}*/
menu->append(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
menu->append(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
menu->append(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
menu->append(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
menu->append(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
menu->appendSeparator("Spelsep");
menu->addChild(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
menu->addChild(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
menu->addChild(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
menu->addChild(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
menu->addChild(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
menu->addSeparator();
menu->setCanTearOff(FALSE);
menu->setVisible(FALSE);
mPopupMenuHandle = menu->getHandle();
@@ -372,18 +372,12 @@ LLTextEditor::~LLTextEditor()
{
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
// Route menu back to the default
if( gEditMenuHandler == this )
{
gEditMenuHandler = NULL;
}
// Scrollbar is deleted by LLView
mHoverSegment = NULL;
std::for_each(mSegments.begin(), mSegments.end(), DeletePointer());
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
LLView::deleteViewByHandle(mPopupMenuHandle);
//LLView::deleteViewByHandle(mPopupMenuHandle);
}
void LLTextEditor::context_cut(void* data)
{
@@ -1283,7 +1277,8 @@ BOOL LLTextEditor::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_
BOOL LLTextEditor::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
// Pretend the mouse is over the scrollbar
return mScrollbar->handleScrollWheel( 0, 0, clicks );
mScrollbar->handleScrollWheel( 0, 0, clicks );
return TRUE;
}
BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -1389,7 +1384,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
SpellMenuBind * tempBind = suggestionMenuItems[i];
if(tempBind)
{
menu->remove(tempBind->menuItem);
menu->removeChild(tempBind->menuItem);
tempBind->menuItem->die();
//delete tempBind->menuItem;
//tempBind->menuItem = NULL;
@@ -1425,7 +1420,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
tempStruct->word, spell_correct, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
menu->addChild(suggMenuItem);
}
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
@@ -1437,7 +1432,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
"Add Word", spell_add, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
menu->addChild(suggMenuItem);
}
}
@@ -1456,7 +1451,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
tempStruct->word, spell_show, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
suggestionMenuItems.push_back(tempStruct);
menu->append(suggMenuItem);
menu->addChild(suggMenuItem);
}
mLastContextMenuX = x;
mLastContextMenuY = y;
@@ -3246,7 +3241,7 @@ void LLTextEditor::drawCursor()
}
// Make sure the IME is in the right place
LLRect screen_pos = getScreenRect();
LLRect screen_pos = calcScreenRect();
LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_left), screen_pos.mBottom + llfloor(cursor_top) );
ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);

View File

@@ -72,7 +72,11 @@ bool LLTrans::parseStrings(const std::string& xml_filename, const std::set<std::
continue;
}
LLTransTemplate xml_template(string_name, string->getTextContents());
std::string contents;
//value is used for strings with preceeding spaces. If not present, fall back to getTextContents()
if(!string->getAttributeString("value",contents))
contents=string->getTextContents();
LLTransTemplate xml_template(string_name, contents);
sStringTemplates[xml_template.mName] = xml_template;
std::set<std::string>::const_iterator iter = default_args.find(xml_template.mName);

View File

@@ -42,10 +42,10 @@ static LLRegisterWidget<LLUICtrl> r("ui_ctrl");
// NOTE: the LLFocusableElement implementation has been moved to llfocusmgr.cpp, to mirror the header where the class is defined.
LLUICtrl::LLUICtrl() :
mViewModel(LLViewModelPtr(new LLViewModel)),
mCommitSignal(NULL),
mValidateSignal(NULL),
mCommitCallback(NULL),
mLostTopCallback(NULL),
mValidateCallback(NULL),
mCallbackUserData(NULL),
mTentative(FALSE),
@@ -63,8 +63,8 @@ LLUICtrl::LLUICtrl(const std::string& name, const LLRect& rect, BOOL mouse_opaqu
LLView( name, rect, mouse_opaque, reshape ),
mCommitSignal(NULL),
mValidateSignal(NULL),
mViewModel(LLViewModelPtr(new LLViewModel)),
mCommitCallback( on_commit_callback),
mLostTopCallback( NULL ),
mValidateCallback( NULL ),
mCallbackUserData( callback_userdata ),
mTentative( FALSE ),
@@ -103,12 +103,33 @@ BOOL LLUICtrl::isCtrl() const
return TRUE;
}
//virtual
void LLUICtrl::setValue(const LLSD& value)
{
mViewModel->setValue(value);
}
//virtual
LLSD LLUICtrl::getValue() const
{
return LLSD();
return mViewModel->getValue();
}
/// When two widgets are displaying the same data (e.g. during a skin
/// change), share their ViewModel.
void LLUICtrl::shareViewModelFrom(const LLUICtrl& other)
{
// Because mViewModel is an LLViewModelPtr, this assignment will quietly
// dispose of the previous LLViewModel -- unless it's already shared by
// somebody else.
mViewModel = other.mViewModel;
}
//virtual
LLViewModel* LLUICtrl::getViewModel() const
{
return mViewModel;
}
// virtual
BOOL LLUICtrl::setTextArg( const std::string& key, const LLStringExplicit& text )
{
@@ -167,58 +188,6 @@ void LLUICtrl::setFocus(BOOL b)
}
}
void LLUICtrl::onFocusReceived()
{
// trigger callbacks
LLFocusableElement::onFocusReceived();
// find first view in hierarchy above new focus that is a LLUICtrl
LLView* viewp = getParent();
LLUICtrl* last_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getLastKeyboardFocus());
while (viewp && !viewp->isCtrl())
{
viewp = viewp->getParent();
}
// and if it has newly gained focus, call onFocusReceived()
LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp);
if (ctrlp && (!last_focus || !last_focus->hasAncestor(ctrlp)))
{
ctrlp->onFocusReceived();
}
}
void LLUICtrl::onFocusLost()
{
// trigger callbacks
LLFocusableElement::onFocusLost();
// find first view in hierarchy above old focus that is a LLUICtrl
LLView* viewp = getParent();
while (viewp && !viewp->isCtrl())
{
viewp = viewp->getParent();
}
// and if it has just lost focus, call onFocusReceived()
LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp);
// hasFocus() includes any descendants
if (ctrlp && !ctrlp->hasFocus())
{
ctrlp->onFocusLost();
}
}
void LLUICtrl::onLostTop()
{
if (mLostTopCallback)
{
mLostTopCallback(this, mCallbackUserData);
}
}
// virtual
void LLUICtrl::setTabStop( BOOL b )
{
@@ -240,12 +209,13 @@ BOOL LLUICtrl::acceptsTextInput() const
//virtual
BOOL LLUICtrl::isDirty() const
{
return FALSE;
return mViewModel->isDirty();
};
//virtual
void LLUICtrl::resetDirty()
{
mViewModel->resetDirty();
}
// virtual

View File

@@ -38,11 +38,13 @@
#include "llrect.h"
#include "llsd.h"
#include "llviewmodel.h" // *TODO move dependency to .cpp file
class LLUICtrl
: public LLView
{
public:
typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t;
typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> commit_signal_t;
typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t;
@@ -56,15 +58,15 @@ public:
U32 reshape=FOLLOWS_NONE);
/*virtual*/ ~LLUICtrl();
// We need this virtual so we can override it with derived versions
virtual LLViewModel* getViewModel() const;
// We shouldn't ever need to set this directly
//virtual void setViewModel(const LLViewModelPtr&);
// LLView interface
/*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent);
/*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
/*virtual*/ BOOL isCtrl() const;
/*virtual*/ void setTentative(BOOL b);
/*virtual*/ BOOL getTentative() const;
// From LLFocusableElement
/*virtual*/ void setFocus( BOOL b );
@@ -77,7 +79,14 @@ public:
virtual class LLCtrlListInterface* getListInterface();
virtual class LLCtrlScrollInterface* getScrollInterface();
virtual void setTentative(BOOL b);
virtual BOOL getTentative() const;
virtual void setValue(const LLSD& value);
virtual LLSD getValue() const;
/// When two widgets are displaying the same data (e.g. during a skin
/// change), share their ViewModel.
virtual void shareViewModelFrom(const LLUICtrl& other);
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
virtual void setIsChrome(BOOL is_chrome);
@@ -89,7 +98,6 @@ public:
virtual void resetDirty(); //Defaults to no-op
// Call appropriate callbacks
virtual void onLostTop(); // called when registered as top ctrl and user clicks elsewhere
virtual void onCommit();
// Default to no-op:
@@ -125,7 +133,6 @@ public:
void setCommitCallback( void (*cb)(LLUICtrl*, void*) ) { mCommitCallback = cb; }
void setValidateBeforeCommit( BOOL(*cb)(LLUICtrl*, void*) ) { mValidateCallback = cb; }
void setLostTopCallback( void (*cb)(LLUICtrl*, void*) ) { mLostTopCallback = cb; }
static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory);
@@ -143,8 +150,9 @@ protected:
commit_signal_t* mCommitSignal;
enable_signal_t* mValidateSignal;
LLViewModelPtr mViewModel;
void (*mCommitCallback)( LLUICtrl* ctrl, void* userdata );
void (*mLostTopCallback)( LLUICtrl* ctrl, void* userdata );
BOOL (*mValidateCallback)( LLUICtrl* ctrl, void* userdata );
void* mCallbackUserData;

View File

@@ -38,6 +38,7 @@
#include "llcallbackmap.h"
#include "llfloater.h"
#include "llinitparam.h"
class LLView;
class LLPanel;

File diff suppressed because it is too large Load Diff

View File

@@ -54,6 +54,7 @@
#include "stdenums.h"
#include "lluistring.h"
#include "llcursortypes.h"
#include "llinitparam.h"
#include "llfocusmgr.h"
const U32 FOLLOWS_NONE = 0x00;
@@ -68,88 +69,6 @@ const BOOL NOT_MOUSE_OPAQUE = FALSE;
const U32 GL_NAME_UI_RESERVED = 2;
/*
// virtual functions defined in LLView:
virtual BOOL isCtrl() const;
LLUICtrl
virtual BOOL isPanel();
LLPanel
virtual void setRect(const LLRect &rect);
LLLineEditor
virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group);
virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
virtual void removeCtrl( LLUICtrl* ctrl);
LLPanel
virtual BOOL canFocusChildren() const { return TRUE; }
LLFolderView
virtual void deleteAllChildren();
LLFolderView, LLPanelInventory
virtual void setTentative(BOOL b) {}
LLUICtrl, LLSliderCtrl, LLSpinCtrl
virtual BOOL getTentative() const { return FALSE; }
LLUICtrl, LLCheckBoxCtrl
virtual void setVisible(BOOL visible);
LLFloater, LLAlertDialog, LLMenuItemGL, LLModalDialog
virtual void setEnabled(BOOL enabled) { mEnabled = enabled; }
LLCheckBoxCtrl, LLComboBox, LLLineEditor, LLMenuGL, LLRadioGroup, etc
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ) { return FALSE; }
LLUICtrl, LLButton, LLCheckBoxCtrl, LLLineEditor, LLMenuGL, LLSliderCtrl
virtual void handleVisibilityChange ( BOOL curVisibilityIn );
LLMenuGL
virtual LLRect getSnapRect() const { return mRect; } *TODO: Make non virtual
LLFloater
virtual LLRect getRequiredRect() { return mRect; }
LLScrolllistCtrl
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
LLUICtrl, et. al.
virtual void translate( S32 x, S32 y );
LLMenuGL
virtual void handleReshape(const LLRect& new_rect, bool by_user = false);
LLFloater, LLScrollLIstVtrl
virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0);
virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0);
LLScrollListCtrl
virtual BOOL canSnapTo(const LLView* other_view) { return other_view != this && other_view->getVisible(); }
LLFloater
virtual void setSnappedTo(const LLView* snap_view) {}
LLFloater
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
*
virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
*
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 draw();
*
*
virtual LLXMLNodePtr getXML(bool save_children = true) const;
*
virtual void initFromXML(LLXMLNodePtr node, LLView* parent);
*
virtual void onFocusLost() {}
LLUICtrl, LLScrollListCtrl, LLMenuGL, LLLineEditor, LLComboBox
virtual void onFocusReceived() {}
LLUICtrl, LLTextEditor, LLScrollListVtrl, LLMenuGL, LLLineEditor
virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
LLTabContainer, LLPanel, LLMenuGL
virtual void setControlName(const std::string& control, LLView *context);
LLSliderCtrl, LLCheckBoxCtrl
virtual std::string getControlName() const { return mControlName; }
LLSliderCtrl, LLCheckBoxCtrl
virtual bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
LLMenuItem
virtual void setValue(const LLSD& value);
*
protected:
virtual BOOL handleKeyHere(KEY key, MASK mask);
*
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
*
*/
class LLUICtrlFactory;
// maps xml strings to widget classes
@@ -209,9 +128,73 @@ public:
}
};
class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElement
class LLView
: public LLMouseHandler, // handles mouse events
public LLFocusableElement, // handles keyboard events
public LLMortician // lazy deletion
//public LLHandleProvider<LLView> // passes out weak references to self
{
public:
struct Follows : public LLInitParam::ChoiceBlock<Follows>
{
Alternative<std::string> string;
Alternative<U32> flags;
Follows();
};
struct Params : public LLInitParam::Block<Params>
{
Mandatory<std::string> name;
Optional<bool> enabled,
visible,
mouse_opaque,
use_bounding_rect,
from_xui,
focus_root;
Optional<S32> tab_group,
default_tab_group;
Optional<std::string> tool_tip;
Optional<S32> sound_flags;
Optional<Follows> follows;
Optional<std::string> hover_cursor;
Optional<std::string> layout;
Optional<LLRect> rect;
// Historical bottom-left layout used bottom_delta and left_delta
// for relative positioning. New layout "topleft" prefers specifying
// based on top edge.
Optional<S32> bottom_delta, // from last bottom to my bottom
top_pad, // from last bottom to my top
top_delta, // from last top to my top
left_pad, // from last right to my left
left_delta; // from last left to my left
//FIXME: get parent context involved in parsing traversal
Ignored needs_translate, // cue for translation tools
xmlns, // xml namespace
xmlns_xsi, // xml namespace
xsi_schemaLocation, // xml schema
xsi_type; // xml schema type
Params();
};
void initFromParams(const LLView::Params&);
protected:
LLView(const LLView::Params&);
//friend class LLUICtrlFactory;
private:
void init(const LLView::Params&);
private:
// widgets in general are not copyable
LLView(const LLView& other) {};
public:
#if LL_DEBUG
static BOOL sIsDrawing;
@@ -294,7 +277,9 @@ public:
void setSoundFlags(U8 flags) { mSoundFlags = flags; }
void setName(std::string name) { mName = name; }
void setUseBoundingRect( BOOL use_bounding_rect );
BOOL getUseBoundingRect();
BOOL getUseBoundingRect() const;
ECursorType getHoverCursor() { return mHoverCursor; }
const std::string& getToolTip() const { return mToolTipMsg.getString(); }
@@ -302,15 +287,14 @@ public:
void sendChildToBack(LLView* child);
void moveChildToFrontOfTabGroup(LLUICtrl* child);
void moveChildToBackOfTabGroup(LLUICtrl* child);
virtual bool addChild(LLView* view, S32 tab_group = 0);
// implemented in terms of addChild()
bool addChildInBack(LLView* view, S32 tab_group = 0);
void addChild(LLView* view, S32 tab_group = 0);
void addChildAtEnd(LLView* view, S32 tab_group = 0);
// remove the specified child from the view, and set it's parent to NULL.
void removeChild(LLView* view, BOOL deleteIt = FALSE);
virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group);
virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
virtual void removeCtrl( LLUICtrl* ctrl);
virtual void removeChild(LLView* view);
child_tab_order_t getCtrlOrder() const { return mCtrlOrder; }
ctrl_list_t getCtrlList() const;
@@ -318,6 +302,7 @@ public:
void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; }
S32 getDefaultTabGroup() const { return mDefaultTabGroup; }
S32 getLastTabGroup() { return mLastTabGroup; }
BOOL isInVisibleChain() const;
BOOL isInEnabledChain() const;
@@ -336,18 +321,19 @@ public:
void setAllChildrenEnabled(BOOL b);
virtual void setVisible(BOOL visible);
BOOL getVisible() const { return mVisible; }
const BOOL& getVisible() const { return mVisible; }
virtual void setEnabled(BOOL enabled);
BOOL getEnabled() const { return mEnabled; }
U8 getSoundFlags() const { return mSoundFlags; }
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
virtual void handleVisibilityChange ( BOOL curVisibilityIn );
virtual void handleVisibilityChange ( BOOL new_visibility );
void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); }
void popVisible() { setVisible(mLastVisible); mLastVisible = TRUE; }
void popVisible() { setVisible(mLastVisible); }
BOOL getLastVisible() const { return mLastVisible; }
LLHandle<LLView> getHandle() { mHandle.bind(this); return mHandle; }
U32 getFollows() const { return mReshapeFlags; }
@@ -360,18 +346,22 @@ public:
const LLRect& getRect() const { return mRect; }
const LLRect& getBoundingRect() const { return mBoundingRect; }
LLRect getLocalBoundingRect() const;
LLRect getScreenRect() const;
LLRect calcScreenRect() const;
LLRect calcScreenBoundingRect() const;
LLRect getLocalRect() const;
virtual LLRect getSnapRect() const;
LLRect getLocalSnapRect() const;
// Override and return required size for this object. 0 for width/height means don't care.
virtual LLRect getRequiredRect();
LLRect calcBoundingRect();
void updateBoundingRect();
LLView* getRootView();
LLView* getParent() const { return mParentView; }
LLView* getFirstChild() const { return (mChildList.empty()) ? NULL : *(mChildList.begin()); }
LLView* findPrevSibling(LLView* child);
LLView* findNextSibling(LLView* child);
S32 getChildCount() const { return (S32)mChildList.size(); }
template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); }
BOOL hasAncestor(const LLView* parentp) const;
@@ -388,6 +378,7 @@ public:
virtual void translate( S32 x, S32 y );
void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); }
BOOL translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside );
BOOL translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside );
void centerWithin(const LLRect& bounds);
void setShape(const LLRect& new_rect, bool by_user = false);
@@ -422,10 +413,6 @@ public:
BOOL getSaveToXML() const { return mSaveToXML; }
void setSaveToXML(BOOL b) { mSaveToXML = b; }
// inherited from LLFocusableElement
/* virtual */ void onFocusLost();
/* virtual */ void onFocusReceived();
typedef enum e_hit_test_type
{
HIT_TEST_USE_BOUNDING_RECT,
@@ -465,6 +452,8 @@ public:
virtual LLSD getValue() const;
const child_list_t* getChildList() const { return &mChildList; }
child_list_const_iter_t beginChild() const { return mChildList.begin(); }
child_list_const_iter_t endChild() const { return mChildList.end(); }
// LLMouseHandler functions
// Default behavior is to pass events to children
@@ -592,12 +581,20 @@ public:
static LLWindow* getWindow(void) { return LLUI::sWindow; }
virtual void handleReshape(const LLRect& rect, bool by_user);
protected:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
//send custom notification to LLView parent
virtual S32 notifyParent(const LLSD& info);
protected:
void drawDebugRect();
void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
void drawChildren();
bool visibleAndContains(S32 local_x, S32 local_Y);
bool visibleEnabledAndContains(S32 local_x, S32 local_y);
void logMouseEvent();
LLView* childrenHandleKey(KEY key, MASK mask);
LLView* childrenHandleUnicodeChar(llwchar uni_char);
@@ -624,18 +621,36 @@ protected:
control_map_t mFloaterControls;
private:
template <typename METHOD, typename XDATA>
LLView* childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDATA extra, bool allow_mouse_block = true);
template <typename METHOD, typename CHARTYPE>
LLView* childrenHandleCharEvent(const std::string& desc, const METHOD& method,
CHARTYPE c, MASK mask);
// adapter to blur distinction between handleKey() and handleUnicodeChar()
// for childrenHandleCharEvent()
BOOL handleUnicodeCharWithDummyMask(llwchar uni_char, MASK /* dummy */, BOOL from_parent)
{
return handleUnicodeChar(uni_char, from_parent);
}
LLView* mParentView;
child_list_t mChildList;
std::string mName;
// location in pixels, relative to surrounding structure, bottom,left=0,0
BOOL mVisible;
LLRect mRect;
LLRect mBoundingRect;
std::string mName;
U32 mReshapeFlags;
child_tab_order_t mCtrlOrder;
S32 mDefaultTabGroup;
S32 mLastTabGroup;
BOOL mEnabled; // Enabled means "accepts input that has an effect on the state of the application."
// A disabled view, for example, may still have a scrollbar that responds to mouse events.
@@ -651,14 +666,9 @@ private:
LLRootHandle<LLView> mHandle;
BOOL mLastVisible;
BOOL mVisible;
S32 mNextInsertionOrdinal;
// <edit>
public:
BOOL mDelayedDelete;
// </edit>
bool mInDraw;
private:
static LLWindow* sWindow; // All root views must know about their window.
@@ -674,6 +684,34 @@ private:
boost::signals2::connection mControlConnection;
ECursorType mHoverCursor;
// This allows special mouse-event targeting logic for testing.
typedef boost::function<bool(const LLView*, S32 x, S32 y)> DrilldownFunc;
static DrilldownFunc sDrilldown;
public:
// This is the only public accessor to alter sDrilldown. This is not
// an accident. The intended usage pattern is like:
// {
// LLView::TemporaryDrilldownFunc scoped_func(myfunctor);
// // ... test with myfunctor ...
// } // exiting block restores original LLView::sDrilldown
class TemporaryDrilldownFunc: public boost::noncopyable
{
public:
TemporaryDrilldownFunc(const DrilldownFunc& func):
mOldDrilldown(sDrilldown)
{
sDrilldown = func;
}
~TemporaryDrilldownFunc()
{
sDrilldown = mOldDrilldown;
}
private:
DrilldownFunc mOldDrilldown;
};
public:
static BOOL sDebugRects; // Draw debug rects behind everything.

157
indra/llui/llviewmodel.cpp Normal file
View File

@@ -0,0 +1,157 @@
/**
* @file llviewmodel.cpp
* @author Nat Goodspeed
* @date 2008-08-08
* @brief Implementation for llviewmodel.
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Precompiled header
#include "linden_common.h"
// associated header
#include "llviewmodel.h"
// STL headers
// std headers
// external library headers
// other Linden headers
///
LLViewModel::LLViewModel()
: mDirty(false)
{
}
/// Instantiate an LLViewModel with an existing data value
LLViewModel::LLViewModel(const LLSD& value)
: mDirty(false)
{
setValue(value);
}
/// Update the stored value
void LLViewModel::setValue(const LLSD& value)
{
mValue = value;
mDirty = true;
}
LLSD LLViewModel::getValue() const
{
return mValue;
}
////////////////////////////////////////////////////////////////////////////
///
LLTextViewModel::LLTextViewModel()
: LLViewModel(false),
mUpdateFromDisplay(false)
{
}
/// Instantiate an LLViewModel with an existing data value
LLTextViewModel::LLTextViewModel(const LLSD& value)
: LLViewModel(value),
mUpdateFromDisplay(false)
{
}
/// Update the stored value
void LLTextViewModel::setValue(const LLSD& value)
{
LLViewModel::setValue(value);
mDisplay = utf8str_to_wstring(value.asString());
// mDisplay and mValue agree
mUpdateFromDisplay = false;
}
void LLTextViewModel::setDisplay(const LLWString& value)
{
// This is the strange way to alter the value. Normally we'd setValue()
// and do the utf8str_to_wstring() to get the corresponding mDisplay
// value. But a text editor might want to edit the display string
// directly, then convert back to UTF8 on commit.
mDisplay = value;
mDirty = true;
// Don't immediately convert to UTF8 -- do it lazily -- we expect many
// more setDisplay() calls than getValue() calls. Just flag that it needs
// doing.
mUpdateFromDisplay = true;
}
LLSD LLTextViewModel::getValue() const
{
// Has anyone called setDisplay() since the last setValue()? If so, have
// to convert mDisplay back to UTF8.
if (mUpdateFromDisplay)
{
// The fact that we're lazily updating fields in this object should be
// transparent to clients, which is why this method is left
// conventionally const. Nor do we particularly want to make these
// members mutable. Just cast away constness in this one place.
LLTextViewModel* nthis = const_cast<LLTextViewModel*>(this);
nthis->mUpdateFromDisplay = false;
nthis->mValue = wstring_to_utf8str(mDisplay);
}
return LLViewModel::getValue();
}
////////////////////////////////////////////////////////////////////////////
LLListViewModel::LLListViewModel(const LLSD& values)
: LLViewModel()
{
}
void LLListViewModel::addColumn(const LLSD& column, EAddPosition pos)
{
}
void LLListViewModel::clearColumns()
{
}
void LLListViewModel::setColumnLabel(const std::string& column, const std::string& label)
{
}
LLScrollListItem* LLListViewModel::addElement(const LLSD& value, EAddPosition pos,
void* userdata)
{
return NULL;
}
LLScrollListItem* LLListViewModel::addSimpleElement(const std::string& value, EAddPosition pos,
const LLSD& id)
{
return NULL;
}
void LLListViewModel::clearRows()
{
}
void LLListViewModel::sortByColumn(const std::string& name, bool ascending)
{
}

214
indra/llui/llviewmodel.h Normal file
View File

@@ -0,0 +1,214 @@
/**
* @file llviewmodel.h
* @author Nat Goodspeed
* @date 2008-08-08
* @brief Define "View Model" classes intended to store data values for use
* by LLUICtrl subclasses. The phrase is borrowed from Microsoft
* terminology, in which "View Model" means the storage object
* underlying a specific widget object -- as in our case -- rather
* than the business "model" object underlying the overall "view"
* presented by the collection of widgets.
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#if ! defined(LL_LLVIEWMODEL_H)
#define LL_LLVIEWMODEL_H
#include "llpointer.h"
#include "llsd.h"
#include "llrefcount.h"
#include "stdenums.h"
#include "llstring.h"
#include <string>
class LLScrollListItem;
class LLViewModel;
class LLTextViewModel;
class LLListViewModel;
// Because LLViewModel is derived from LLRefCount, always pass, store
// and return LLViewModelPtr rather than plain LLViewModel*.
typedef LLPointer<LLViewModel> LLViewModelPtr;
typedef LLPointer<LLTextViewModel> LLTextViewModelPtr;
typedef LLPointer<LLListViewModel> LLListViewModelPtr;
/**
* LLViewModel stores a scalar LLSD data item, the current display value of a
* scalar LLUICtrl widget. LLViewModel subclasses are used to store data
* collections used for aggregate widgets. LLViewModel is ref-counted because
* -- for multiple skins -- we may have distinct widgets sharing the same
* LLViewModel data. This way, the LLViewModel is quietly deleted when the
* last referencing widget is destroyed.
*/
class LLViewModel: public LLRefCount
{
public:
LLViewModel();
/// Instantiate an LLViewModel with an existing data value
LLViewModel(const LLSD& value);
/// Update the stored value
virtual void setValue(const LLSD& value);
/// Get the stored value, in appropriate type.
virtual LLSD getValue() const;
/// Has the value been changed since last time we checked?
bool isDirty() const { return mDirty; }
/// Once the value has been saved to a file, or otherwise consumed by the
/// app, we no longer need to enable the Save button
void resetDirty() { mDirty = false; }
//
void setDirty() { mDirty = true; }
protected:
LLSD mValue;
bool mDirty;
};
/**
* LLTextViewModel stores a value displayed as text.
*/
class LLTextViewModel: public LLViewModel
{
public:
LLTextViewModel();
/// Instantiate an LLViewModel with an existing data value
LLTextViewModel(const LLSD& value);
// LLViewModel functions
virtual void setValue(const LLSD& value);
virtual LLSD getValue() const;
// New functions
/// Get the stored value in string form
const LLWString& getDisplay() const { return mDisplay; }
/**
* Set the display string directly (see LLTextEditor). What the user is
* editing is actually the LLWString value rather than the underlying
* UTF-8 value.
*/
void setDisplay(const LLWString& value);
private:
/// To avoid converting every widget's stored value from LLSD to LLWString
/// every frame, cache the converted value
LLWString mDisplay;
/// As the user edits individual characters (setDisplay()), defer
/// LLWString-to-UTF8 conversions until s/he's done.
bool mUpdateFromDisplay;
};
/**
* LLListViewModel stores a list of data items. The semantics are borrowed
* from LLScrollListCtrl.
*/
class LLListViewModel: public LLViewModel
{
public:
LLListViewModel() {}
LLListViewModel(const LLSD& values);
virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM);
virtual void clearColumns();
virtual void setColumnLabel(const std::string& column, const std::string& label);
virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM,
void* userdata = NULL);
virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos,
const LLSD& id);
virtual void clearRows();
virtual void sortByColumn(const std::string& name, bool ascending);
};
//namespace LLViewModel
//{
// class Value
// {
// public:
// Value(const LLSD& value = LLSD());
//
// LLSD getValue() const { return mValue; }
// void setValue(const LLSD& value) { mValue = value; }
//
// bool isAvailable() const { return false; }
// bool isReadOnly() const { return false; }
//
// bool undo() { return false; }
// bool redo() { return false; }
//
// /// Has the value been changed since last time we checked?
// bool isDirty() const { return mDirty; }
// /// Once the value has been saved to a file, or otherwise consumed by the
// /// app, we no longer need to enable the Save button
// void resetDirty() { mDirty = false; }
// //
// void setDirty() { mDirty = true; }
//
// protected:
// LLSD mValue;
// bool mDirty;
// };
//
// class Numeric : public Value
// {
// public:
// Numeric(S32 value = 0);
// Numeric(F32 value);
//
// F32 getPrecision();
// F32 getMin();
// F32 getMax();
//
// void increment();
// void decrement();
// };
//
// class MultipleValues : public Value
// {
// class Selector
// {};
//
// MultipleValues();
// virtual S32 numElements();
// };
//
// class Tuple : public MultipleValues
// {
// Tuple(S32 size);
// LLSD getValue(S32 which) const;
// void setValue(S32 which, const LLSD& value);
// };
//
// class List : public MultipleValues
// {
// List();
//
// void add(const ValueModel& value);
// bool remove(const Selector& item);
//
// void setSortElement(const Selector& element);
// void sort();
// };
//
//};
#endif /* ! defined(LL_LLVIEWMODEL_H) */