diff options
author | brad kittenbrink <brad@lindenlab.com> | 2009-08-05 18:45:18 -0700 |
---|---|---|
committer | brad kittenbrink <brad@lindenlab.com> | 2009-08-05 18:45:18 -0700 |
commit | a8d216e194327c7bee8a42c983f7f2ca01adb385 (patch) | |
tree | 76819d6e78c7e7cf0c5e54d319847f4731c77205 /indra/llui | |
parent | 860a82863966435bea680d8541f051e99a6c226c (diff) | |
parent | 24d146a9ff26af1f3e4cf5af2c5238ca42e2c6c7 (diff) |
Merged in my DEV-35401 "doubleton" fix.
Diffstat (limited to 'indra/llui')
28 files changed, 337 insertions, 568 deletions
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 51f9d6bd18..f8c6204afb 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -100,7 +100,8 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) mPrearrangeCallback(p.prearrange_callback()), mTextEntryCallback(p.text_entry_callback()), mSelectionCallback(p.selection_callback()), - mListPosition(p.list_position) + mListPosition(p.list_position), + mLastSelectedIndex(-1) { // Text label button @@ -117,6 +118,8 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p) mArrowImage = button_params.image_unselected; mButton = LLUICtrlFactory::create<LLButton>(button_params); + + if(mAllowTextEntry) { //redo to compensate for button hack that leaves space for a character @@ -430,7 +433,8 @@ void LLComboBox::setButtonVisible(BOOL visible) LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); if (visible) { - text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * drop_shadow_button; + S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; + text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button; } //mTextEntry->setRect(text_entry_rect); mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE); @@ -472,14 +476,15 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p) LLRect rect = getLocalRect(); if (mAllowTextEntry) { + S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; S32 shadow_size = drop_shadow_button; - mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size, + mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size, rect.mTop, rect.mRight, rect.mBottom)); mButton->setTabStop(FALSE); mButton->setHAlign(LLFontGL::HCENTER); LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); - text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * drop_shadow_button; + text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button; // clear label on button std::string cur_label = mButton->getLabelSelected(); LLLineEditor::Params params = p.combo_editor; @@ -621,15 +626,15 @@ void LLComboBox::showList() mList->setVisible(TRUE); setUseBoundingRect(TRUE); + + mList->sortItems(); + mLastSelectedIndex = mList->getFirstSelectedIndex(); } void LLComboBox::hideList() { - //*HACK: store the original value explicitly somewhere, not just in label - std::string orig_selection = mAllowTextEntry ? mTextEntry->getText() : mButton->getLabelSelected(); - // assert selection in list - mList->selectItemByLabel(orig_selection, FALSE); + mList->selectNthItem(mLastSelectedIndex); mButton->setToggleState(FALSE); mList->setVisible(FALSE); @@ -687,6 +692,7 @@ void LLComboBox::onItemSelected(const LLSD& data) const std::string name = mList->getSelectedItemLabel(); S32 cur_id = getCurrentIndex(); + mLastSelectedIndex = cur_id; if (cur_id != -1) { setLabel(name); diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 517210f629..db97b0df75 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -232,5 +232,6 @@ private: commit_callback_t mPrearrangeCallback; commit_callback_t mTextEntryCallback; commit_callback_t mSelectionCallback; + S32 mLastSelectedIndex; }; #endif diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index a397278a2b..d420d1141e 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -75,6 +75,19 @@ std::string LLFloater::sButtonActiveImageNames[BUTTON_COUNT] = "Icon_Undock_Foreground" }; +// Empty string means programmatic glow effect, achieved by +// not setting explicit image. +std::string LLFloater::sButtonHoveredImageNames[BUTTON_COUNT] = +{ + "", //BUTTON_CLOSE + "restore_pressed.tga", //BUTTON_RESTORE + "minimize_pressed.tga", //BUTTON_MINIMIZE + "tearoff_pressed.tga", //BUTTON_TEAR_OFF + "close_in_blue.tga", //BUTTON_EDIT + "", //BUTTON_DOCK + "", //BUTTON_UNDOCK +}; + std::string LLFloater::sButtonPressedImageNames[BUTTON_COUNT] = { "Icon_Close_Press", //BUTTON_CLOSE @@ -97,20 +110,19 @@ std::string LLFloater::sButtonNames[BUTTON_COUNT] = "llfloater_undock_btn" }; -std::string LLFloater::sButtonToolTips[BUTTON_COUNT] = {}; - +std::string LLFloater::sButtonToolTips[BUTTON_COUNT]; std::string LLFloater::sButtonToolTipsIndex[BUTTON_COUNT]= { #ifdef LL_DARWIN - "BUTTON_CLOSE_DARWIN",//LLTrans::getString("BUTTON_CLOSE_DARWIN"), //"Close (Cmd-W)", //BUTTON_CLOSE + "BUTTON_CLOSE_DARWIN", //"Close (Cmd-W)", //BUTTON_CLOSE #else - "BUTTON_CLOSE_WIN", //LLTrans::getString("BUTTON_CLOSE_WIN"), //"Close (Ctrl-W)", //BUTTON_CLOSE + "BUTTON_CLOSE_WIN", //"Close (Ctrl-W)", //BUTTON_CLOSE #endif - "BUTTON_RESTORE",//LLTrans::getString("BUTTON_RESTORE"), //"Restore", //BUTTON_RESTORE - "BUTTON_MINIMIZE",//LLTrans::getString("BUTTON_MINIMIZE"), //"Minimize", //BUTTON_MINIMIZE - "BUTTON_TEAR_OFF",//LLTrans::getString("BUTTON_TEAR_OFF"), //"Tear Off", //BUTTON_TEAR_OFF - "BUTTON_EDIT", //LLTrans::getString("BUTTON_EDIT"), // "Edit", //BUTTON_EDIT + "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE + "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE + "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF + "BUTTON_EDIT", //"Edit", //BUTTON_EDIT "BUTTON_DOCK", "BUTTON_UNDOCK" }; @@ -128,7 +140,7 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] = LLMultiFloater* LLFloater::sHostp = NULL; BOOL LLFloater::sEditModeEnabled = FALSE; -BOOL LLFloater::sQuitting = FALSE; // Temporary hack until onClose() behavior becomes data driven +BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting LLFloater::handle_map_t LLFloater::sFloaterMap; LLFloaterView* gFloaterView = NULL; @@ -219,6 +231,15 @@ const LLFloater::Params& LLFloater::getDefaultParams() return LLUICtrlFactory::getDefaultParams<LLFloater>(); } +//static +void LLFloater::initClass() +{ + // translate tooltips for floater buttons + for (S32 i = 0; i < BUTTON_COUNT; i++) + { + sButtonToolTips[i] = LLTrans::getString( sButtonToolTipsIndex[i] ); + } +} LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) : LLPanel(), @@ -251,22 +272,11 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) static LLUIColor default_background_color = LLUIColorTable::instance().getColor("FloaterDefaultBackgroundColor"); static LLUIColor focus_background_color = LLUIColorTable::instance().getColor("FloaterFocusBackgroundColor"); - for (S32 i = 0; i < BUTTON_COUNT; i++) - { - sButtonToolTips[i] =LLTrans::getString( sButtonToolTipsIndex[i]); - } - mHandle.bind(this); mNotificationContext = new LLFloaterNotificationContext(getHandle()); mBgColorAlpha = default_background_color; mBgColorOpaque = focus_background_color; - for (S32 i = 0; i < 4; i++) - { - mResizeBar[i] = NULL; - mResizeHandle[i] = NULL; - } - // Clicks stop here. setMouseOpaque(TRUE); @@ -431,6 +441,9 @@ void LLFloater::addResizeCtrls() // Resize handles (corners) LLResizeHandle::Params handle_p; + // handles must not be mouse-opaque, otherwise they block hover events + // to other buttons like the close box. JC + handle_p.mouse_opaque(false); handle_p.rect(LLRect( getRect().getWidth() - RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT, getRect().getWidth(), 0)); handle_p.min_width(mMinWidth); handle_p.min_height(mMinHeight); @@ -505,7 +518,6 @@ void LLFloater::storeRectControl() void LLFloater::storeVisibilityControl() { - // sQuitting is a temp hack until we standardize onClose() behavior so that it won't call this when quitting if( !sQuitting && mVisibilityControl.size() > 1 ) { LLUI::sSettingGroups["floater"]->setBOOL( mVisibilityControl, getVisible() ); @@ -514,7 +526,7 @@ void LLFloater::storeVisibilityControl() void LLFloater::setVisible( BOOL visible ) { - LLPanel::setVisible(visible); + LLPanel::setVisible(visible); // calls handleVisibilityChange() if( visible && mFirstLook ) { mFirstLook = FALSE; @@ -549,14 +561,14 @@ void LLFloater::setVisible( BOOL visible ) } // virtual -void LLFloater::onVisibilityChange ( BOOL new_visibility ) +void LLFloater::handleVisibilityChange ( BOOL new_visibility ) { if (new_visibility) { if (getHost()) getHost()->setFloaterFlashing(this, FALSE); } - LLPanel::onVisibilityChange ( new_visibility ); + LLPanel::handleVisibilityChange ( new_visibility ); } void LLFloater::openFloater(const LLSD& key) @@ -593,7 +605,7 @@ void LLFloater::openFloater(const LLSD& key) setVisibleAndFrontmost(mAutoFocus); } - mOpenSignal(this, getValue()); + mOpenSignal(this, key); onOpen(key); } @@ -601,7 +613,7 @@ void LLFloater::closeFloater(bool app_quitting) { if (app_quitting) { - LLFloater::sQuitting = true; // Temp hack until we standardize onClose() + LLFloater::sQuitting = true; } // Always unminimize before trying to close. @@ -661,9 +673,27 @@ void LLFloater::closeFloater(bool app_quitting) } } - // Let floater do cleanup. - mCloseSignal(this, getValue(), app_quitting); - onClose(app_quitting); + // Close callback + mCloseSignal(this, LLSD(app_quitting)); + + // Hide or Destroy + if (mSingleInstance) + { + // Hide the instance + if (getHost()) + { + getHost()->setVisible(FALSE); + } + else + { + setVisible(FALSE); + } + } + else + { + setVisible(FALSE); // hide before destroying (so handleVisibilityChange() gets called) + destroy(); + } } } @@ -1771,9 +1801,20 @@ void LLFloater::buildButtons() p.rect(btn_rect); p.label(""); p.image_unselected.name(sButtonActiveImageNames[i]); + // Selected, no matter if hovered or not, is "pressed" p.image_selected.name(sButtonPressedImageNames[i]); p.image_hover_selected.name(sButtonPressedImageNames[i]); - p.image_hover_unselected.name(sButtonPressedImageNames[i]); + // Empty string means programmatic glow effect, achieved by + // not setting explicit image. + if (sButtonHoveredImageNames[i].empty()) + { + // These icons are really small, need glow amount increased + p.hover_glow_amount( 0.22f ); + } + else + { + p.image_hover_unselected.name(sButtonHoveredImageNames[i]); + } p.click_callback.function(boost::bind(sButtonCallbacks[i], this)); p.tab_stop(false); p.follows.flags(FOLLOWS_TOP|FOLLOWS_RIGHT); @@ -1788,72 +1829,6 @@ void LLFloater::buildButtons() updateButtons(); } -void LLFloater::initOpenCallback(const OpenCallbackParam& cb, open_signal_t& sig) -{ - if (cb.function.isProvided()) - { - if (cb.parameter.isProvided()) - sig.connect(boost::bind(cb.function(), _1, cb.parameter)); - else - sig.connect(cb.function()); - } - else - { - std::string function_name = cb.function_name; - open_callback_t* func = (OpenCallbackRegistry::getValue(function_name)); - if (func) - { - if (cb.parameter.isProvided()) - sig.connect(boost::bind((*func), _1, cb.parameter)); - else - sig.connect(*func); - } - else if (!function_name.empty()) - { - llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl; - } - } -} - -void LLFloater::initCloseCallback(const CloseCallbackParam& cb, close_signal_t& sig) -{ - if (cb.function.isProvided()) - { - if (cb.parameter.isProvided()) - sig.connect(boost::bind(cb.function(), _1, cb.parameter, _3)); - else - sig.connect(cb.function()); - } - else - { - std::string function_name = cb.function_name; - close_callback_t* func = (CloseCallbackRegistry::getValue(function_name)); - if (func) - { - if (cb.parameter.isProvided()) - sig.connect(boost::bind((*func), _1, cb.parameter,_3)); - else - sig.connect(*func); - } - else if (!function_name.empty()) - { - llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl; - } - } -} - -namespace LLInitParam -{ - - template<> - bool ParamCompare<LLFloater::close_callback_t>::equals( - const LLFloater::close_callback_t &a, - const LLFloater::close_callback_t &b) - { - return false; - } -} - ///////////////////////////////////////////////////// // LLFloaterView @@ -2612,13 +2587,13 @@ void LLFloater::initFromParams(const LLFloater::Params& p) // open callback if (p.open_callback.isProvided()) - initOpenCallback(p.open_callback, mOpenSignal); + initCommitCallback(p.open_callback, mOpenSignal); // close callback if (p.close_callback.isProvided()) - initCloseCallback(p.close_callback, mCloseSignal); + initCommitCallback(p.close_callback, mCloseSignal); } -void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floater, LLXMLNodePtr output_node) +void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { Params params(LLUICtrlFactory::getDefaultParams<LLFloater>()); LLXUIParser::instance().readXUI(node, params); @@ -2661,38 +2636,6 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floa applyRectControl(); // If we have a saved rect control, apply it gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen - if (open_floater) - { - this->openFloater(getKey()); - } - moveResizeHandlesToFront(); } -// visibility methods -bool VisibilityPolicy<LLFloater>::visible(LLFloater* instance, const LLSD& key) -{ - if (instance) - { - return !instance->isMinimized() && instance->isInVisibleChain(); - } - return FALSE; -} - -void VisibilityPolicy<LLFloater>::show(LLFloater* instance, const LLSD& key) -{ - if (instance) - { - instance->openFloater(key); - if (instance->getHost()) - { - instance->getHost()->openFloater(key); - } - } -} - -void VisibilityPolicy<LLFloater>::hide(LLFloater* instance, const LLSD& key) -{ - if (instance) instance->closeFloater(); -} - diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index f6c6dcf277..ee066317e0 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -97,7 +97,7 @@ public: enum EFloaterButtons { - BUTTON_CLOSE, + BUTTON_CLOSE = 0, BUTTON_RESTORE, BUTTON_MINIMIZE, BUTTON_TEAR_OFF, @@ -107,22 +107,6 @@ public: BUTTON_COUNT }; - typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> open_callback_t; - typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> open_signal_t; - - typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param, bool app_quitting)> close_callback_t; - typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param, bool app_quitting)> close_signal_t; - - struct OpenCallbackParam : public LLInitParam::Block<OpenCallbackParam, CallbackParam > - { - Optional<open_callback_t> function; - }; - - struct CloseCallbackParam : public LLInitParam::Block<CloseCallbackParam, CallbackParam > - { - Optional<close_callback_t> function; - }; - struct Params : public LLInitParam::Block<Params, LLPanel::Params> { @@ -140,8 +124,8 @@ public: save_visibility, can_dock; - Optional<OpenCallbackParam> open_callback; - Optional<CloseCallbackParam> close_callback; + Optional<CommitCallbackParam> open_callback, + close_callback; Params(); }; @@ -149,7 +133,10 @@ public: // use this to avoid creating your own default LLFloater::Param instance static const Params& getDefaultParams(); - LLFloater(const LLSD& key = LLSD(), const Params& params = getDefaultParams()); + // Load translations for tooltips for standard buttons + static void initClass(); + + LLFloater(const LLSD& key, const Params& params = getDefaultParams()); virtual ~LLFloater(); @@ -157,7 +144,7 @@ public: static void setupParamsForExport(Params& p, LLView* parent); void initFromParams(const LLFloater::Params& p); - void initFloaterXML(LLXMLNodePtr node, LLView *parent, BOOL open_floater = TRUE, LLXMLNodePtr output_node = NULL); + void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false); /*virtual*/ BOOL canSnapTo(const LLView* other_view); @@ -171,7 +158,6 @@ public: void openFloater(const LLSD& key = LLSD()); // If allowed, close the floater cleanly, releasing focus. - // app_quitting is passed to onClose() below. void closeFloater(bool app_quitting = false); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -221,20 +207,16 @@ public: virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); virtual void draw(); - + + // *TODO: Eliminate this in favor of mOpenSignal virtual void onOpen(const LLSD& key) {} - // Call destroy() to free memory, or setVisible(FALSE) to keep it - // If app_quitting, you might not want to save your visibility. - // Defaults to destroy(). - virtual void onClose(bool app_quitting) { destroy(); } - // This cannot be "const" until all derived floater canClose() // methods are const as well. JC virtual BOOL canClose() { return TRUE; } - virtual void setVisible(BOOL visible); - virtual void onVisibilityChange ( BOOL curVisibilityIn ); + /*virtual*/ void setVisible(BOOL visible); // do not override + /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override void setFrontmost(BOOL take_focus = TRUE); @@ -250,7 +232,9 @@ public: LLHandle<LLFloater> getHandle() const { return mHandle; } const LLSD& getKey() { return mKey; } BOOL matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); } - + + const std::string& getInstanceName() { return mInstanceName; } + bool isDockable() const { return mCanDock; } void setCanDock(bool b); @@ -299,10 +283,7 @@ protected: void setAutoFocus(BOOL focus) { mAutoFocus = focus; } // whether to automatically take focus when opened LLDragHandle* getDragHandle() const { return mDragHandle; } - void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC - - void initOpenCallback(const OpenCallbackParam& cb, open_signal_t& sig); - void initCloseCallback(const CloseCallbackParam& cb, close_signal_t& sig); + void destroy() { die(); } // Don't call this directly. You probably want to call closeFloater() private: void setForeground(BOOL b); // called only by floaterview @@ -314,15 +295,11 @@ private: void addResizeCtrls(); void addDragHandle(); -public: - class OpenCallbackRegistry : public CallbackRegistry<open_callback_t, OpenCallbackRegistry> {}; - class CloseCallbackRegistry : public CallbackRegistry<close_callback_t, CloseCallbackRegistry> {}; - protected: std::string mRectControl; std::string mVisibilityControl; - open_signal_t mOpenSignal; - close_signal_t mCloseSignal; + commit_signal_t mOpenSignal; // Called when floater is opened, passes mKey + commit_signal_t mCloseSignal; // Called when floater is closed, passes app_qitting as LLSD() LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg LLDragHandle* mDragHandle; @@ -376,6 +353,8 @@ private: static BOOL sEditModeEnabled; static BOOL sQuitting; static std::string sButtonActiveImageNames[BUTTON_COUNT]; + // Images to use when cursor hovered over an enabled button + static std::string sButtonHoveredImageNames[BUTTON_COUNT]; static std::string sButtonPressedImageNames[BUTTON_COUNT]; static std::string sButtonNames[BUTTON_COUNT]; static std::string sButtonToolTips[BUTTON_COUNT]; @@ -465,37 +444,12 @@ private: S32 mSnapOffsetRight; }; -//******************************************************* -//* TO BE DEPRECATED -//******************************************************* -// visibility policy specialized for floaters -template<> -class VisibilityPolicy<LLFloater> -{ -public: - // visibility methods - static bool visible(LLFloater* instance, const LLSD& key); - - static void show(LLFloater* instance, const LLSD& key); - - static void hide(LLFloater* instance, const LLSD& key); -}; - // // Globals // extern LLFloaterView* gFloaterView; -namespace LLInitParam -{ - template<> - bool ParamCompare<LLFloater::close_callback_t>::equals( - const LLFloater::close_callback_t &a, - const LLFloater::close_callback_t &b); -} - - #endif // LL_FLOATER_H diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index d12f600503..a63b1b085c 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -121,8 +121,7 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key) res = build_func(key); - const bool DONT_OPEN_FLOATER = false; - LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, DONT_OPEN_FLOATER); + LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL); // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe res->mKey = key; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index ad2d8afe45..e355cfda8b 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -89,7 +89,6 @@ const U32 RIGHT_PAD_PIXELS = 2; const U32 RIGHT_WIDTH_PIXELS = 15; const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS; -const U32 ACCEL_PAD_PIXELS = 10; const U32 PLAIN_PAD_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS + RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS; const U32 BRIEF_PAD_PIXELS = 2; @@ -302,7 +301,7 @@ U32 LLMenuItemGL::getNominalHeight( void ) const // Get the parent menu for this item -LLMenuGL* LLMenuItemGL::getMenu() +LLMenuGL* LLMenuItemGL::getMenu() const { return (LLMenuGL*) getParent(); } @@ -326,7 +325,7 @@ U32 LLMenuItemGL::getNominalWidth( void ) const if( KEY_NONE != mAcceleratorKey ) { - width += ACCEL_PAD_PIXELS; + width += getMenu()->getShortcutPad(); std::string temp; appendAcceleratorString( temp ); width += mFont->getWidth( temp ); @@ -515,12 +514,13 @@ BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit& return TRUE; } -void LLMenuItemGL::onVisibilityChange(BOOL new_visibility) +void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility) { if (getMenu()) { getMenu()->needsArrange(); } + LLView::handleVisibilityChange(new_visibility); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1067,13 +1067,13 @@ void LLMenuItemBranchGL::updateBranchParent(LLView* parentp) } } -void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility ) +void LLMenuItemBranchGL::handleVisibilityChange( BOOL new_visibility ) { if (new_visibility == FALSE && getBranch() && !getBranch()->getTornOff()) { getBranch()->setVisible(FALSE); } - LLMenuItemGL::onVisibilityChange(new_visibility); + LLMenuItemGL::handleVisibilityChange(new_visibility); } BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) @@ -1587,7 +1587,8 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p) mJumpKey(p.jump_key), mCreateJumpKeys(p.create_jump_keys), mParentFloaterHandle(p.parent_floater), - mNeedsArrange(FALSE) + mNeedsArrange(FALSE), + mShortcutPad(p.shortcut_pad) { typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep("_"); @@ -3213,6 +3214,8 @@ BOOL LLMenuBarGL::handleHover( S32 x, S32 y, MASK mask ) ///============================================================================ /// Class LLMenuHolderGL ///============================================================================ +LLCoordGL LLMenuHolderGL::sContextMenuSpawnPos(S32_MAX, S32_MAX); + LLMenuHolderGL::LLMenuHolderGL() : LLPanel() { @@ -3273,6 +3276,19 @@ BOOL LLMenuHolderGL::handleRightMouseDown( S32 x, S32 y, MASK mask ) // down, move off the menu, then mouse-up. We want this to close the menu. BOOL LLMenuHolderGL::handleRightMouseUp( S32 x, S32 y, MASK mask ) { + const S32 SLOP = 2; + S32 spawn_dx = (x - sContextMenuSpawnPos.mX); + S32 spawn_dy = (y - sContextMenuSpawnPos.mY); + if (-SLOP <= spawn_dx && spawn_dx <= SLOP + && -SLOP <= spawn_dy && spawn_dy <= SLOP) + { + // we're still inside the slop region from spawning this menu + // so interpret the mouse-up as a single-click to show and leave on + // screen + sContextMenuSpawnPos.set(S32_MAX, S32_MAX); + return TRUE; + } + BOOL handled = LLView::childrenHandleRightMouseUp(x, y, mask) != NULL; if (!handled) { @@ -3344,7 +3360,7 @@ void LLMenuHolderGL::setActivatedItem(LLMenuItemGL* item) /// Class LLTearOffMenu ///============================================================================ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : - LLFloater() + LLFloater(LLSD()) { static LLUICachedControl<S32> floater_header_size ("UIFloaterHeaderSize", 0); @@ -3377,6 +3393,16 @@ LLTearOffMenu::LLTearOffMenu(LLMenuGL* menup) : mMenu->highlightNextItem(NULL); } +LLTearOffMenu::~LLTearOffMenu() +{ +} + +// virtual +BOOL LLTearOffMenu::postBuild() +{ + mCloseSignal.connect(boost::bind(&LLTearOffMenu::closeTearOff, this)); + return TRUE; +} void LLTearOffMenu::draw() { @@ -3476,7 +3502,7 @@ LLTearOffMenu* LLTearOffMenu::create(LLMenuGL* menup) return tearoffp; } -void LLTearOffMenu::onClose(bool app_quitting) +void LLTearOffMenu::closeTearOff() { removeChild(mMenu); mOldParent->addChild(mMenu); @@ -3486,7 +3512,6 @@ void LLTearOffMenu::onClose(bool app_quitting) mMenu->setVisible(FALSE); mMenu->setTornOff(FALSE); mMenu->setDropShadowed(TRUE); - destroy(); } @@ -3600,9 +3625,7 @@ static MenuRegistry::Register<LLContextMenu> context_menu_register2("context_men LLContextMenu::LLContextMenu(const Params& p) : LLMenuGL(p), mHoveredAnyItem(FALSE), - mHoverItem(NULL), - mSpawnMouseX(S32_MAX), // definitely not inside the window frame - mSpawnMouseY(S32_MAX) + mHoverItem(NULL) { //setBackgroundVisible(TRUE); } @@ -3616,6 +3639,11 @@ void LLContextMenu::setVisible(BOOL visible) // Takes cursor position in screen space? void LLContextMenu::show(S32 x, S32 y) { + // Save click point for detecting cursor moves before mouse-up. + // Must be in local coords to compare with mouseUp events. + // If the mouse doesn't move, the menu will stay open ala the Mac. + LLMenuHolderGL::sContextMenuSpawnPos.set(x,y); + arrangeAndClear(); S32 width = getRect().getWidth(); @@ -3652,15 +3680,11 @@ void LLContextMenu::show(S32 x, S32 y) S32 local_x, local_y; parent_view->screenPointToLocal(x, y, &local_x, &local_y); - // HACK: casting away const. Should use setRect or some helper function instead. - const_cast<LLRect&>(getRect()).setCenterAndSize(local_x + width/2, local_y - height/2, width, height); + LLRect rect; + rect.setLeftTopAndSize(local_x, local_y, width, height); + setRect(rect); arrange(); - // Save click point for detecting cursor moves before mouse-up. - // Must be in local coords to compare with mouseUp events. - // If the mouse doesn't move, the menu will stay open ala the Mac. - screenPointToLocal(x, y, &mSpawnMouseX, &mSpawnMouseY); - LLView::setVisible(TRUE); } @@ -3758,20 +3782,6 @@ BOOL LLContextMenu::handleRightMouseDown(S32 x, S32 y, MASK mask) BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask ) { - const S32 SLOP = 2; - S32 spawn_dx = (x - mSpawnMouseX); - S32 spawn_dy = (y - mSpawnMouseY); - if (-SLOP <= spawn_dx && spawn_dx <= SLOP - && -SLOP <= spawn_dy && spawn_dy <= SLOP) - { - // we're still inside the slop region from spawning this menu - // so interpret the mouse-up as a single-click to show and leave on - // screen - mSpawnMouseX = S32_MAX; - mSpawnMouseY = S32_MAX; - return TRUE; - } - S32 local_x = x - getRect().mLeft; S32 local_y = y - getRect().mBottom; diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index f786c891d7..828956a217 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -106,7 +106,7 @@ protected: friend class LLUICtrlFactory; public: virtual void setValue(const LLSD& value) { setLabel(value.asString()); } - /*virtual*/ void onVisibilityChange(BOOL new_visibility); + /*virtual*/ void handleVisibilityChange(BOOL new_visibility); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleAcceleratorKey(KEY key, MASK mask); @@ -137,7 +137,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 @@ -383,6 +383,7 @@ public: keep_fixed_size, scrollable; Optional<LLUIColor> bg_color; + Optional<S32> shortcut_pad; Params() : jump_key("jump_key", KEY_NONE), @@ -392,7 +393,8 @@ public: bg_visible("bg_visible", true), create_jump_keys("create_jump_keys", false), bg_color("bg_color", LLUIColorTable::instance().getColor( "MenuDefaultBgColor" )), - scrollable("scrollable", false) + scrollable("scrollable", false), + shortcut_pad("shortcut_pad") { addSynonym(bg_visible, "opaque"); addSynonym(bg_color, "color"); @@ -513,6 +515,8 @@ public: static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; } static BOOL getKeyboardMode() { return sKeyboardMode; } + S32 getShortcutPad() { return mShortcutPad; } + void scrollItemsUp(); void scrollItemsDown(); BOOL isScrollable() const { return mScrollable; } @@ -566,6 +570,7 @@ private: LLHandle<LLFloater> mParentFloaterHandle; KEY mJumpKey; BOOL mCreateJumpKeys; + S32 mShortcutPad; }; // end class LLMenuGL @@ -621,7 +626,7 @@ public: virtual void updateBranchParent( LLView* parentp ); // LLView Functionality - virtual void onVisibilityChange( BOOL curVisibilityIn ); + virtual void handleVisibilityChange( BOOL curVisibilityIn ); virtual void draw(); @@ -680,11 +685,6 @@ public: protected: BOOL mHoveredAnyItem; LLMenuItemGL* mHoverItem; - - // Cursor position when the menu was spawned, in menu-local coords - // Used to allow single right-click within a slop region to spawn the menu - S32 mSpawnMouseX; - S32 mSpawnMouseY; }; @@ -764,6 +764,8 @@ public: virtual void draw(); 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 const LLRect getMenuRect() const { return getLocalRect(); } @@ -771,6 +773,10 @@ public: 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; @@ -788,8 +794,10 @@ class LLTearOffMenu : public LLFloater { public: static LLTearOffMenu* create(LLMenuGL* menup); - virtual ~LLTearOffMenu() {} - virtual void onClose(bool app_quitting); + virtual ~LLTearOffMenu(); + + virtual BOOL postBuild(); + virtual void draw(void); virtual void onFocusReceived(); virtual void onFocusLost(); @@ -799,7 +807,9 @@ public: private: LLTearOffMenu(LLMenuGL* menup); - + + void closeTearOff(); + LLView* mOldParent; LLMenuGL* mMenu; F32 mTargetHeight; diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 7557b87b94..11fa290de1 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -44,12 +44,11 @@ // static std::list<LLModalDialog*> LLModalDialog::sModalStack; -LLModalDialog::LLModalDialog( const std::string& title, S32 width, S32 height, BOOL modal ) - : LLFloater(), +LLModalDialog::LLModalDialog( const LLSD& key, S32 width, S32 height, BOOL modal ) + : LLFloater(key), mModal( modal ) { setRect(LLRect( 0, height, width, 0 )); - setTitle(title); if (modal) { setCanMinimize(FALSE); @@ -59,6 +58,7 @@ LLModalDialog::LLModalDialog( const std::string& title, S32 width, S32 height, B setBackgroundVisible(TRUE); setBackgroundOpaque(TRUE); centerOnScreen(); // default position + mCloseSignal.connect(boost::bind(&LLModalDialog::stopModal, this)); } LLModalDialog::~LLModalDialog() @@ -68,6 +68,18 @@ LLModalDialog::~LLModalDialog() { gFocusMgr.unlockFocus(); } + + std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this); + if (iter != sModalStack.end()) + { + llerrs << "Attempt to delete dialog while still in sModalStack!" << llendl; + } +} + +// virtual +BOOL LLModalDialog::postBuild() +{ + return LLFloater::postBuild(); } // virtual @@ -235,12 +247,6 @@ BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask ) } } -void LLModalDialog::onClose(bool app_quitting) -{ - stopModal(); - LLFloater::onClose(app_quitting); -} - // virtual void LLModalDialog::draw() { diff --git a/indra/llui/llmodaldialog.h b/indra/llui/llmodaldialog.h index dad92ab82a..4d5073024b 100644 --- a/indra/llui/llmodaldialog.h +++ b/indra/llui/llmodaldialog.h @@ -45,9 +45,11 @@ class LLModalDialog; class LLModalDialog : public LLFloater { public: - LLModalDialog( const std::string& title, S32 width, S32 height, BOOL modal = true ); + LLModalDialog( const LLSD& key, S32 width, S32 height, BOOL modal = true ); /*virtual*/ ~LLModalDialog(); - + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void openFloater(const LLSD& key = LLSD()); /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -63,8 +65,6 @@ public: /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); - /*virtual*/ void onClose(bool app_quitting); - /*virtual*/ void setVisible(BOOL visible); /*virtual*/ void draw(); diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index 22683d7950..9f9e3aecac 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -42,8 +42,8 @@ // LLMultiFloater // -LLMultiFloater::LLMultiFloater(const LLFloater::Params& params) - : LLFloater(), +LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params) + : LLFloater(key), mTabContainer(NULL), mTabPos(LLTabContainer::TOP), mAutoResize(TRUE), @@ -74,20 +74,12 @@ void LLMultiFloater::buildTabContainer() void LLMultiFloater::onOpen(const LLSD& key) { - if (mTabContainer->getTabCount() <= 0) - { - // for now, don't allow multifloaters - // without any child floaters - closeFloater(); - } -} - -void LLMultiFloater::onClose(bool app_quitting) -{ - if(closeAllFloaters() == TRUE) - { - LLFloater::onClose(app_quitting); - }//else not all tabs could be closed... +// if (mTabContainer->getTabCount() <= 0) +// { +// // for now, don't allow multifloaters +// // without any child floaters +// closeFloater(); +// } } void LLMultiFloater::draw() @@ -124,7 +116,8 @@ BOOL LLMultiFloater::closeAllFloaters() //Tab did not actually close, possibly due to a pending Save Confirmation dialog.. //so try and close the next one in the list... tabToClose++; - }else + } + else { //Tab closed ok. lastTabCount = mTabContainer->getTabCount(); @@ -246,6 +239,9 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater, { floaterp->setVisible(FALSE); } + + // Tabs sometimes overlap resize handle + moveResizeHandlesToFront(); } /** @@ -448,6 +444,8 @@ void LLMultiFloater::setCanResize(BOOL can_resize) BOOL LLMultiFloater::postBuild() { + mCloseSignal.connect(boost::bind(&LLMultiFloater::closeAllFloaters, this)); + // remember any original xml minimum size getResizeLimits(&mOrigMinWidth, &mOrigMinHeight); diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index 7f4c1c040a..bbf2c56fe7 100644 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -44,14 +44,13 @@ class LLMultiFloater : public LLFloater { public: - LLMultiFloater(const LLFloater::Params& params = LLFloater::getDefaultParams()); + LLMultiFloater(const LLSD& key, const Params& params = getDefaultParams()); virtual ~LLMultiFloater() {}; void buildTabContainer(); virtual BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void draw(); /*virtual*/ void setVisible(BOOL visible); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 78a0b9f3fe..0335a265b6 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -100,8 +100,9 @@ // and we need this to manage the notification callbacks #include "llevents.h" #include "llfunctorregistry.h" -#include "llui.h" -#include "llmemory.h" +#include "llpointer.h" +#include "llinitparam.h" +#include "llxmlnode.h" #include "llnotificationslistener.h" class LLNotification; @@ -159,7 +160,8 @@ public: LLNotificationForm(); LLNotificationForm(const LLSD& sd); - LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node); + LLNotificationForm(const std::string& name, + const LLPointer<LLXMLNode> xml_node); LLSD asLLSD() const; @@ -835,7 +837,7 @@ public: // load notification descriptions from file; // OK to call more than once because it will reload bool loadTemplates(); - LLXMLNodePtr checkForXMLTemplate(LLXMLNodePtr item); + LLPointer<class LLXMLNode> checkForXMLTemplate(LLPointer<class LLXMLNode> item); // Add a simple notification (from XUI) void addFromCallback(const LLSD& name); @@ -918,7 +920,7 @@ private: std::string mFileName; - typedef std::map<std::string, LLXMLNodePtr> XMLTemplateMap; + typedef std::map<std::string, LLPointer<class LLXMLNode> > XMLTemplateMap; XMLTemplateMap mXmlTemplates; LLNotificationMap mUniqueNotifications; diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 9fb38bc316..1a948fdd00 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -74,7 +74,8 @@ LLPanel::Params::Params() min_height("min_height", 100), strings("string"), filename("filename"), - class_name("class") + class_name("class"), + visible_callback("visible_callback") { name = "panel"; addSynonym(background_visible, "bg_visible"); @@ -307,6 +308,12 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask ) return handled; } +void LLPanel::handleVisibilityChange ( BOOL new_visibility ) +{ + LLUICtrl::handleVisibilityChange ( new_visibility ); + mVisibleSignal(this, LLSD(new_visibility) ); // Pass BOOL as LLSD +} + BOOL LLPanel::checkRequirements() { if (!mRequirementsError.empty()) @@ -426,7 +433,11 @@ void LLPanel::initFromParams(const LLPanel::Params& p) // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible LLUICtrl::initFromParams(p); - + + // visible callback + if (p.visible_callback.isProvided()) + initCommitCallback(p.visible_callback, mVisibleSignal); + for (LLInitParam::ParamIterator<LocalizedString>::const_iterator it = p.strings().begin(); it != p.strings().end(); ++it) diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 4140e3aa93..552a621a8e 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -88,7 +88,9 @@ public: Optional<std::string> class_name; Multiple<LocalizedString> strings; - + + Optional<CommitCallbackParam> visible_callback; + Params(); }; @@ -111,6 +113,7 @@ public: /*virtual*/ BOOL isPanel() const; /*virtual*/ void draw(); /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask ); + /*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // Override to set not found list: /*virtual*/ LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; @@ -254,6 +257,8 @@ protected: CommitCallbackRegistry::ScopedRegistrar mCommitCallbackRegistrar; EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar; + commit_signal_t mVisibleSignal; // Called when visibilit changes, passes new visibility as LLSD() + private: // Unified error reporting for the child* functions typedef std::set<std::string> expected_members_list_t; @@ -273,7 +278,7 @@ private: ui_string_map_t mUIStrings; std::string mRequirementsError; - + }; // end class LLPanel #endif diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 3312064131..bc489592d4 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -56,8 +56,10 @@ LLScrollbar::Params::Params() doc_pos ("doc_pos", 0), page_size ("page_size", 0), step_size ("step_size", 1), - thumb_image("thumb_image"), - track_image("track_image"), + thumb_image_vertical("thumb_image_vertical"), + thumb_image_horizontal("thumb_image_horizontal"), + track_image_vertical("track_image_vertical"), + track_image_horizontal("track_image_horizontal"), track_color("track_color"), thumb_color("thumb_color"), thickness("thickness"), @@ -86,8 +88,10 @@ LLScrollbar::LLScrollbar(const Params & p) mThumbColor ( p.thumb_color() ), mOnScrollEndCallback( NULL ), mOnScrollEndData( NULL ), - mThumbImage(p.thumb_image), - mTrackImage(p.track_image), + mThumbImageV(p.thumb_image_vertical), + mThumbImageH(p.thumb_image_horizontal), + mTrackImageV(p.track_image_vertical), + mTrackImageH(p.track_image_horizontal), mThickness(p.thickness.isProvided() ? p.thickness : LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize")) { updateThumbRect(); @@ -493,7 +497,8 @@ void LLScrollbar::draw() } // Draw background and thumb. - if (mTrackImage.isNull() || mThumbImage.isNull()) + if ( ( mOrientation == VERTICAL&&(mThumbImageV.isNull() || mThumbImageV.isNull()) ) + || (mOrientation == HORIZONTAL&&(mTrackImageH.isNull() || mThumbImageH.isNull()) )) { gl_rect_2d(mOrientation == HORIZONTAL ? mThickness : 0, mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(), @@ -505,30 +510,54 @@ void LLScrollbar::draw() } else { - // Background - mTrackImage->drawSolid(mOrientation == HORIZONTAL ? mThickness : 0, - mOrientation == VERTICAL ? mThickness : 0, - mOrientation == HORIZONTAL ? getRect().getWidth() - 2 * mThickness : getRect().getWidth(), - mOrientation == VERTICAL ? getRect().getHeight() - 2 * mThickness : getRect().getHeight(), - mTrackColor.get()); - // Thumb LLRect outline_rect = mThumbRect; outline_rect.stretch(2); - - if (gFocusMgr.getKeyboardFocus() == this) + S32 rect_fix = 0; + // Background + + if(mOrientation == HORIZONTAL) { - mTrackImage->draw(outline_rect, gFocusMgr.getFocusColor()); + mTrackImageH->drawSolid(mThickness //S32 x + , 0 //S32 y + , getRect().getWidth() - 2 * mThickness //S32 width + , getRect().getHeight()- rect_fix //S32 height + , mTrackColor.get()); //const LLColor4& color + + if (gFocusMgr.getKeyboardFocus() == this) + { + mTrackImageH->draw(outline_rect, gFocusMgr.getFocusColor()); + } + + mThumbImageH->draw(mThumbRect, mThumbColor.get()); + if (mCurGlowStrength > 0.01f) + { + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + mThumbImageH->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + } - - mThumbImage->draw(mThumbRect, mThumbColor.get()); - if (mCurGlowStrength > 0.01f) + else if(mOrientation == VERTICAL) { - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - mThumbImage->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + mTrackImageV->drawSolid( 0+rect_fix //S32 x + , mThickness //S32 y + , getRect().getWidth() //S32 width + , getRect().getHeight() - 2 * mThickness //S32 height + , mTrackColor.get()); //const LLColor4& color + if (gFocusMgr.getKeyboardFocus() == this) + { + mTrackImageV->draw(outline_rect, gFocusMgr.getFocusColor()); + } + + mThumbImageV->draw(mThumbRect, mThumbColor.get()); + if (mCurGlowStrength > 0.01f) + { + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + mThumbImageV->drawSolid(mThumbRect, LLColor4(1.f, 1.f, 1.f, mCurGlowStrength)); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } } - } BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax()); diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 43604d37b7..5522e5d0fa 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -61,8 +61,10 @@ public: Optional<S32> step_size; Optional<S32> thickness; - Optional<LLUIImage*> thumb_image, - track_image; + Optional<LLUIImage*> thumb_image_vertical, + thumb_image_horizontal, + track_image_horizontal, + track_image_vertical; Optional<LLUIColor> track_color, thumb_color; @@ -155,8 +157,10 @@ private: LLUIColor mTrackColor; LLUIColor mThumbColor; - LLUIImagePtr mThumbImage; - LLUIImagePtr mTrackImage; + LLUIImagePtr mThumbImageV; + LLUIImagePtr mThumbImageH; + LLUIImagePtr mTrackImageV; + LLUIImagePtr mTrackImageH; S32 mThickness; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index e8627586ea..79f0f9d71b 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -163,7 +163,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mSorted(FALSE), mDirty(FALSE), mOriginalSelection(-1), - mDrewSelected(FALSE), mLastSelected(NULL), mHeadingHeight(p.heading_height), mAllowMultipleSelection(p.multi_select), @@ -1353,8 +1352,6 @@ void LLScrollListCtrl::drawItems() S32 cur_y = y; - mDrewSelected = FALSE; - S32 line = 0; S32 max_columns = 0; @@ -1375,11 +1372,6 @@ void LLScrollListCtrl::drawItems() //llinfos << item_rect.getWidth() << llendl; - if (item->getSelected()) - { - mDrewSelected = TRUE; - } - max_columns = llmax(max_columns, item->getNumColumns()); LLColor4 fg_color; @@ -1444,10 +1436,7 @@ void LLScrollListCtrl::draw() LLLocalClipRect clip(getLocalRect()); // if user specifies sort, make sure it is maintained - if (needsSorting() && !isSorted()) - { - sortItems(); - } + sortItems(); if (mNeedsScroll) { @@ -2208,6 +2197,8 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending) sort_column->mSortDirection = ascending ? LLScrollListColumn::ASCENDING : LLScrollListColumn::DESCENDING; sort_column_t new_sort_column(column_idx, ascending); + + setSorted(FALSE); if (mSortColumns.empty()) { @@ -2248,21 +2239,22 @@ void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending) // First column is column 0 void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending) { - if (setSort(column, ascending)) - { - sortItems(); - } + setSort(column, ascending); + sortItems(); } void LLScrollListCtrl::sortItems() { - // do stable sort to preserve any previous sorts - std::stable_sort( - mItemList.begin(), - mItemList.end(), - SortScrollListItem(mSortColumns)); + if (hasSortOrder() && !isSorted()) + { + // do stable sort to preserve any previous sorts + std::stable_sort( + mItemList.begin(), + mItemList.end(), + SortScrollListItem(mSortColumns)); - setSorted(TRUE); + setSorted(TRUE); + } } // for one-shot sorts, does not save sort column/order @@ -2318,10 +2310,7 @@ void LLScrollListCtrl::scrollToShowSelected() return; } - if (needsSorting() && !isSorted()) - { - sortItems(); - } + sortItems(); S32 index = getFirstSelectedIndex(); if (index < 0) @@ -2562,7 +2551,7 @@ std::string LLScrollListCtrl::getSortColumnName() else return ""; } -BOOL LLScrollListCtrl::needsSorting() +BOOL LLScrollListCtrl::hasSortOrder() { return !mSortColumns.empty(); } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index c1800419be..e699711bd4 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -329,7 +329,7 @@ public: std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } - BOOL needsSorting(); + BOOL hasSortOrder(); S32 selectMultiple( std::vector<LLUUID> ids ); void sortItems(); @@ -374,9 +374,6 @@ private: void commitIfChanged(); BOOL setSort(S32 column, BOOL ascending); - S32 mCurIndex; // For get[First/Next]Data - S32 mCurSelectedIndex; // For get[First/Next]Selected - S32 mLineHeight; // the max height of a single line S32 mScrollLines; // how many lines we've scrolled down S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight @@ -445,11 +442,6 @@ private: typedef std::pair<S32, BOOL> sort_column_t; std::vector<sort_column_t> mSortColumns; - - // HACK: Did we draw one selected item this frame? - BOOL mDrewSelected; - - LLTextBox* mCommentTextBox; }; // end class LLScrollListCtrl #endif // LL_SCROLLLISTCTRL_H diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 3516712dc9..fbcbb55b85 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -39,20 +39,20 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) : LLUICtrl(p) { - const S32 fudge = 2; - S32 btn_height = getRect().getHeight() - (fudge * 2); + S32 btn_top = p.search_button.top_pad + p.search_button.rect.height; + S32 btn_right = p.search_button.rect.width + p.search_button.left_pad; + LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad); LLLineEditor::Params line_editor_params(p); line_editor_params.name("filter edit box"); line_editor_params.rect(getLocalRect()); line_editor_params.follows.flags(FOLLOWS_ALL); - line_editor_params.text_pad_left(btn_height + fudge); + line_editor_params.text_pad_left(p.text_pad_left + search_btn_rect.getWidth()); line_editor_params.commit_callback.function(boost::bind(&LLUICtrl::onCommit, this)); mSearchEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_params); addChild(mSearchEditor); - LLRect search_btn_rect(fudge, fudge + btn_height, fudge + btn_height, fudge); LLButton::Params button_params(p.search_button); button_params.name(std::string("clear filter")); button_params.rect(search_btn_rect) ; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index adeaf0a279..48816e4b9e 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -286,6 +286,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) mReflowNeeded(FALSE), mScrollNeeded(FALSE), mLastSelectionY(-1), + mParseHTML(FALSE), + mParseHighlights(FALSE), mTabsToNextField(p.ignore_tab), mGLFont(p.font) { @@ -335,7 +337,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) setHideScrollbarForShortDocs(p.hide_scrollbar); - mParseHTML=FALSE; mHTML.clear(); } @@ -398,6 +399,7 @@ void LLTextEditor::updateLineStartList(S32 startpos) S32 seg_idx = 0; S32 seg_offset = 0; + if (!mLineStartList.empty()) { getSegmentAndOffset(startpos, &seg_idx, &seg_offset); diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 4da91cc1d7..0babd7ba58 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -515,6 +515,7 @@ private: S32 mDesiredXPixel; // X pixel position where the user wants the cursor to be LLRect mTextRect; // The rect in which text is drawn. Excludes borders. // List of offsets and segment index of the start of each line. Always has at least one node (0). + struct pred; struct line_info { line_info(S32 segment, S32 offset) : mSegment(segment), mOffset(offset) {} diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 6906f0befb..fab8f61356 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1860,10 +1860,11 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname) for (settings_map_t::iterator itor = sSettingGroups.begin(); itor != sSettingGroups.end(); ++itor) { - if(itor->second!= NULL) + LLControlGroup* control_group = itor->second; + if(control_group != NULL) { - if (sSettingGroups[(itor->first)]->controlExists(controlname)) - return *sSettingGroups[(itor->first)]; + if (control_group->controlExists(controlname)) + return *control_group; } } diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 413733a50b..b1943a7b02 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -222,193 +222,6 @@ private: static std::vector<std::string> sXUIPaths; }; -// FactoryPolicy is a static class that controls the creation and lookup of UI elements, -// such as floaters. -// The key parameter is used to provide a unique identifier and/or associated construction -// parameters for a given UI instance -// -// Specialize this traits for different types, or provide a class with an identical interface -// in the place of the traits parameter -// -// For example: -// -// template <> -// class FactoryPolicy<MyClass> /* FactoryPolicy specialized for MyClass */ -// { -// public: -// static MyClass* findInstance(const LLSD& key = LLSD()) -// { -// /* return instance of MyClass associated with key */ -// } -// -// static MyClass* createInstance(const LLSD& key = LLSD()) -// { -// /* create new instance of MyClass using key for construction parameters */ -// } -// } -// -// class MyClass : public LLUIFactory<MyClass> -// { -// /* uses FactoryPolicy<MyClass> by default */ -// } - -template <class T> -class FactoryPolicy -{ -public: - // basic factory methods - static T* findInstance(const LLSD& key); // unimplemented, provide specialiation - static T* createInstance(const LLSD& key); // unimplemented, provide specialiation -}; - -// VisibilityPolicy controls the visibility of UI elements, such as floaters. -// The key parameter is used to store the unique identifier of a given UI instance -// -// Specialize this traits for different types, or duplicate this interface for specific instances -// (see above) - -template <class T> -class VisibilityPolicy -{ -public: - // visibility methods - static bool visible(T* instance, const LLSD& key); // unimplemented, provide specialiation - static void show(T* instance, const LLSD& key); // unimplemented, provide specialiation - static void hide(T* instance, const LLSD& key); // unimplemented, provide specialiation -}; - -// Manages generation of UI elements by LLSD, such that (generally) there is -// a unique instance per distinct LLSD parameter -// Class T is the instance type being managed, and the FACTORY_POLICY and VISIBILITY_POLICY -// classes provide static methods for creating, accessing, showing and hiding the associated -// element T -template <class T, class FACTORY_POLICY = FactoryPolicy<T>, class VISIBILITY_POLICY = VisibilityPolicy<T> > -class LLUIFactory -{ -public: - // give names to the template parameters so derived classes can refer to them - // except this doesn't work in gcc - typedef FACTORY_POLICY factory_policy_t; - typedef VISIBILITY_POLICY visibility_policy_t; - - LLUIFactory() - { - } - - virtual ~LLUIFactory() - { - } - - // default show and hide methods - static T* showInstance(const LLSD& key = LLSD()) - { - T* instance = getInstance(key); - if (instance != NULL) - { - VISIBILITY_POLICY::show(instance, key); - } - return instance; - } - - static void hideInstance(const LLSD& key = LLSD()) - { - T* instance = getInstance(key); - if (instance != NULL) - { - VISIBILITY_POLICY::hide(instance, key); - } - } - - static void toggleInstance(const LLSD& key = LLSD()) - { - if (instanceVisible(key)) - { - hideInstance(key); - } - else - { - showInstance(key); - } - } - - static bool instanceVisible(const LLSD& key = LLSD()) - { - T* instance = FACTORY_POLICY::findInstance(key); - return instance != NULL && VISIBILITY_POLICY::visible(instance, key); - } - - static T* getInstance(const LLSD& key = LLSD()) - { - T* instance = FACTORY_POLICY::findInstance(key); - if (instance == NULL) - { - instance = FACTORY_POLICY::createInstance(key); - } - return instance; - } - -}; - - -// Creates a UI singleton by ignoring the identifying parameter -// and always generating the same instance via the LLUIFactory interface. -// Note that since UI elements can be destroyed by their hierarchy, this singleton -// pattern uses a static pointer to an instance that will be re-created as needed. -// -// Usage Pattern: -// -// class LLFloaterFoo : public LLFloater, public LLUISingleton<LLFloaterFoo> -// { -// friend class LLUISingleton<LLFloaterFoo>; -// private: -// LLFloaterFoo(const LLSD& key); -// }; -// -// Note that LLUISingleton takes an option VisibilityPolicy parameter that defines -// how showInstance(), hideInstance(), etc. work. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLUISingleton&oldid=79352 - -template <class T, class VISIBILITY_POLICY = VisibilityPolicy<T> > -class LLUISingleton: public LLUIFactory<T, LLUISingleton<T, VISIBILITY_POLICY>, VISIBILITY_POLICY> -{ -protected: - - // T must derive from LLUISingleton<T> - LLUISingleton() { sInstance = static_cast<T*>(this); } - ~LLUISingleton() { sInstance = NULL; } - -public: - static T* findInstance(const LLSD& key = LLSD()) - { - return sInstance; - } - - static T* createInstance(const LLSD& key = LLSD()) - { - if (sInstance == NULL) - { - sInstance = new T(key); - } - return sInstance; - } - - static void destroyInstance() - { - delete sInstance; - sInstance = NULL; - } - - static bool instanceExists() { return NULL != sInstance; } - -private: - LLUISingleton(const LLUISingleton&){} - LLUISingleton& operator=(const LLUISingleton&){} -private: - static T* sInstance; -}; - -template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL; class LLScreenClipRect { diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index aae4a86d87..19d1d4040c 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -125,7 +125,9 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel) mViewModel(viewmodel), mControlVariable(NULL), mEnabledControlVariable(NULL), - mDisabledControlVariable(NULL) + mDisabledControlVariable(NULL), + mMakeVisibleControlVariable(NULL), + mMakeInvisibleControlVariable(NULL) { mUICtrlHandle.bind(this); } diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 3b2b56d48e..586b988c43 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -196,7 +196,7 @@ static LLFastTimer::DeclareTimer BUILD_FLOATERS("Build Floaters"); //----------------------------------------------------------------------------- // buildFloater() //----------------------------------------------------------------------------- -void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, BOOL open_floater, LLXMLNodePtr output_node) +void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node) { LLFastTimer timer(BUILD_FLOATERS); LLXMLNodePtr root; @@ -236,7 +236,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen floaterp->getCommitCallbackRegistrar().pushScope(); floaterp->getEnableCallbackRegistrar().pushScope(); - floaterp->initFloaterXML(root, floaterp->getParent(), open_floater, output_node); + floaterp->initFloaterXML(root, floaterp->getParent(), output_node); if (LLUI::sShowXUINames) { @@ -254,13 +254,6 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen mFileNames.pop_back(); } -LLFloater* LLUICtrlFactory::buildFloaterFromXML(const std::string& filename, BOOL open_floater) -{ - LLFloater* floater = new LLFloater(); - buildFloater(floater, filename, open_floater); - return floater; -} - //----------------------------------------------------------------------------- // saveToXML() //----------------------------------------------------------------------------- diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 6374018ca6..9dbe458bae 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -267,8 +267,7 @@ public: return ParamDefaults<typename T::Params, 0>::instance().get(); } - void buildFloater(LLFloater* floaterp, const std::string &filename, BOOL open_floater = TRUE, LLXMLNodePtr output_node = NULL); - LLFloater* buildFloaterFromXML(const std::string& filename, BOOL open_floater = TRUE); + void buildFloater(LLFloater* floaterp, const std::string &filename, LLXMLNodePtr output_node); BOOL buildPanel(LLPanel* panelp, const std::string &filename, LLXMLNodePtr output_node = NULL); // Does what you want for LLFloaters and LLPanels diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 2f9a6e7d46..d94472a8e5 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -603,14 +603,14 @@ void LLView::setVisible(BOOL visible) if (!getParent() || getParent()->isInVisibleChain()) { // tell all children of this view that the visibility may have changed - onVisibilityChange( visible ); + handleVisibilityChange( visible ); } updateBoundingRect(); } } // virtual -void LLView::onVisibilityChange ( BOOL new_visibility ) +void LLView::handleVisibilityChange ( BOOL new_visibility ) { for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) { @@ -618,7 +618,7 @@ void LLView::onVisibilityChange ( BOOL new_visibility ) // only views that are themselves visible will have their overall visibility affected by their ancestors if (viewp->getVisible()) { - viewp->onVisibilityChange ( new_visibility ); + viewp->handleVisibilityChange ( new_visibility ); } } } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 9138b04258..ee49276139 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -93,7 +93,7 @@ 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 onVisibilityChange ( BOOL curVisibilityIn ); +virtual void handleVisibilityChange ( BOOL curVisibilityIn ); LLMenuGL virtual LLRect getSnapRect() const { return mRect; } *TODO: Make non virtual LLFloater @@ -349,7 +349,7 @@ public: virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); - virtual void onVisibilityChange ( BOOL curVisibilityIn ); + virtual void handleVisibilityChange ( BOOL new_visibility ); void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void popVisible() { setVisible(mLastVisible); } |