diff options
author | Richard Linden <none@none> | 2011-12-12 12:32:22 -0800 |
---|---|---|
committer | Richard Linden <none@none> | 2011-12-12 12:32:22 -0800 |
commit | 40a74eb5b77493e66587a01b6655d405c75e3a59 (patch) | |
tree | 201c40c39d653c92a3745043094cd03a3713eee9 | |
parent | 29570bdc96af39579a09ec77ec9cb74ab124f682 (diff) |
EXP-1711 FIX LLWindowShade doesn't stack multiple notifications
-rw-r--r-- | indra/llui/lllayoutstack.h | 3 | ||||
-rw-r--r-- | indra/llui/llpanel.h | 2 | ||||
-rw-r--r-- | indra/llui/llwindowshade.cpp | 207 | ||||
-rw-r--r-- | indra/llui/llwindowshade.h | 10 | ||||
-rw-r--r-- | indra/newview/llmediactrl.cpp | 46 | ||||
-rw-r--r-- | indra/newview/llpanelprimmediacontrols.cpp | 3 |
6 files changed, 163 insertions, 108 deletions
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index ede6149a80..3b308a359d 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -191,13 +191,12 @@ public: return min_dim; } + F32 getCollapseFactor(); void setOrientation(LLLayoutStack::ELayoutOrientation orientation) { mOrientation = orientation; } protected: LLLayoutPanel(const Params& p); - F32 getCollapseFactor(); - bool mExpandedMinDimSpecified; S32 mExpandedMinDim; diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index cd33938226..f620201020 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -135,6 +135,8 @@ public: const LLColor4& getBackgroundColor() const { return mBgOpaqueColor; } void setTransparentColor(const LLColor4& color) { mBgAlphaColor = color; } const LLColor4& getTransparentColor() const { return mBgAlphaColor; } + void setBackgroundImage(LLUIImage* image) { mBgOpaqueImage = image; } + void setTransparentImage(LLUIImage* image) { mBgAlphaImage = image; } LLPointer<LLUIImage> getBackgroundImage() const { return mBgOpaqueImage; } LLPointer<LLUIImage> getTransparentImage() const { return mBgAlphaImage; } LLColor4 getBackgroundImageOverlay() { return mBgOpaqueImageOverlay; } diff --git a/indra/llui/llwindowshade.cpp b/indra/llui/llwindowshade.cpp index cf76202215..0b4cfe68a6 100644 --- a/indra/llui/llwindowshade.cpp +++ b/indra/llui/llwindowshade.cpp @@ -37,6 +37,8 @@ const S32 MIN_NOTIFICATION_AREA_HEIGHT = 30; const S32 MAX_NOTIFICATION_AREA_HEIGHT = 100; +static LLDefaultChildRegistry::Register<LLWindowShade> r("window_shade"); + LLWindowShade::Params::Params() : bg_image("bg_image"), modal("modal", false), @@ -48,7 +50,6 @@ LLWindowShade::Params::Params() LLWindowShade::LLWindowShade(const LLWindowShade::Params& params) : LLUICtrl(params), - mNotification(params.notification), mModal(params.modal), mFormHeight(0), mTextColor(params.text_color) @@ -72,7 +73,7 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params) addChild(stackp); LLLayoutPanel::Params panel_p; - panel_p.rect = LLRect(0, 30, 800, 0); + panel_p.rect = LLRect(0, MIN_NOTIFICATION_AREA_HEIGHT, 800, 0); panel_p.name = "notification_area"; panel_p.visible = false; panel_p.user_resize = false; @@ -107,11 +108,11 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params) LLIconCtrl::Params icon_p; icon_p.name = "notification_icon"; - icon_p.rect = LLRect(5, 23, 21, 8); + icon_p.rect = LLRect(5, 25, 21, 10); panel->addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_p)); LLTextBox::Params text_p; - text_p.rect = LLRect(31, 20, panel->getRect().getWidth() - 5, 0); + text_p.rect = LLRect(31, 23, panel->getRect().getWidth() - 5, 3); text_p.follows.flags = FOLLOWS_ALL; text_p.text_color = mTextColor; text_p.font = LLFontGL::getFontSansSerifSmall(); @@ -125,41 +126,132 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params) panel_p.auto_resize = false; panel_p.user_resize = false; panel_p.name="form_elements"; - panel_p.rect = LLRect(0, 30, 130, 0); + panel_p.rect = LLRect(0, MIN_NOTIFICATION_AREA_HEIGHT, 130, 0); LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); stackp->addChild(form_elements_panel); - if (params.can_close) + panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); + panel_p.auto_resize = false; + panel_p.user_resize = false; + panel_p.rect = LLRect(0, MIN_NOTIFICATION_AREA_HEIGHT, 25, 0); + panel_p.name = "close_panel"; + LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); + stackp->addChild(close_panel); + + LLButton::Params button_p; + button_p.name = "close_notification"; + button_p.rect = LLRect(5, 23, 21, 7); + button_p.image_color.control="DkGray_66"; + button_p.image_unselected.name="Icon_Close_Foreground"; + button_p.image_selected.name="Icon_Close_Press"; + button_p.click_callback.function = boost::bind(&LLWindowShade::onCloseNotification, this); + + close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p)); + + close_panel->setVisible(params.can_close); +} + +void LLWindowShade::draw() +{ + LLRect message_rect = getChild<LLTextBox>("notification_text")->getTextBoundingRect(); + + LLLayoutPanel* notification_area = getChild<LLLayoutPanel>("notification_area"); + + notification_area->reshape(notification_area->getRect().getWidth(), + llclamp(message_rect.getHeight() + 15, + llmin(mFormHeight, MAX_NOTIFICATION_AREA_HEIGHT), + MAX_NOTIFICATION_AREA_HEIGHT)); + + LLUICtrl::draw(); + + while(!mNotifications.empty() && !mNotifications.back()->isActive()) + { + mNotifications.pop_back(); + // go ahead and hide + hide(); + } + + if (mNotifications.empty()) + { + hide(); + } + else if (notification_area->getCollapseFactor() < 0.01f) + { + displayLatestNotification(); + } + + if (!notification_area->getVisible() && (notification_area->getCollapseFactor() < 0.001f)) + { + getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(false); + setMouseOpaque(false); + } +} + +void LLWindowShade::hide() +{ + getChildRef<LLLayoutPanel>("notification_area").setVisible(false); +} + +void LLWindowShade::onCloseNotification() +{ + if (!mNotifications.empty()) + LLNotifications::instance().cancel(mNotifications.back()); +} + +void LLWindowShade::onClickIgnore(LLUICtrl* ctrl) +{ + LLNotificationPtr notify = getCurrentNotification(); + if (!notify) return; + + bool check = ctrl->getValue().asBoolean(); + if (notify->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) { - panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>(); - panel_p.auto_resize = false; - panel_p.user_resize = false; - panel_p.rect = LLRect(0, 30, 25, 0); - LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p); - stackp->addChild(close_panel); - - LLButton::Params button_p; - button_p.name = "close_notification"; - button_p.rect = LLRect(5, 23, 21, 7); - button_p.image_color.control="DkGray_66"; - button_p.image_unselected.name="Icon_Close_Foreground"; - button_p.image_selected.name="Icon_Close_Press"; - button_p.click_callback.function = boost::bind(&LLWindowShade::onCloseNotification, this); - - close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p)); + // question was "show again" so invert value to get "ignore" + check = !check; } + notify->setIgnored(check); +} + +void LLWindowShade::onClickNotificationButton(const std::string& name) +{ + LLNotificationPtr notify = getCurrentNotification(); + if (!notify) return; - LLSD payload = mNotification->getPayload(); + mNotificationResponse[name] = true; - LLNotificationFormPtr formp = mNotification->getForm(); + notify->respond(mNotificationResponse); +} + +void LLWindowShade::onEnterNotificationText(LLUICtrl* ctrl, const std::string& name) +{ + mNotificationResponse[name] = ctrl->getValue().asString(); +} + +void LLWindowShade::show(LLNotificationPtr notification) +{ + mNotifications.push_back(notification); + + displayLatestNotification(); +} + +void LLWindowShade::displayLatestNotification() +{ + if (mNotifications.empty()) return; + + LLNotificationPtr notification = mNotifications.back(); + + LLSD payload = notification->getPayload(); + + LLNotificationFormPtr formp = notification->getForm(); LLLayoutPanel& notification_area = getChildRef<LLLayoutPanel>("notification_area"); - notification_area.getChild<LLUICtrl>("notification_icon")->setValue(mNotification->getIcon()); - notification_area.getChild<LLUICtrl>("notification_text")->setValue(mNotification->getMessage()); - notification_area.getChild<LLUICtrl>("notification_text")->setToolTip(mNotification->getMessage()); + notification_area.getChild<LLUICtrl>("notification_icon")->setValue(notification->getIcon()); + notification_area.getChild<LLUICtrl>("notification_text")->setValue(notification->getMessage()); + notification_area.getChild<LLUICtrl>("notification_text")->setToolTip(notification->getMessage()); LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType(); LLLayoutPanel& form_elements = notification_area.getChildRef<LLLayoutPanel>("form_elements"); form_elements.deleteAllChildren(); + form_elements.reshape(form_elements.getRect().getWidth(), MIN_NOTIFICATION_AREA_HEIGHT); const S32 FORM_PADDING_HORIZONTAL = 10; const S32 FORM_PADDING_VERTICAL = 3; @@ -229,7 +321,7 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params) label_p.v_pad = 5; LLTextBox* textbox = LLUICtrlFactory::create<LLTextBox>(label_p); textbox->reshapeToFitText(); - textbox->reshape(textbox->getRect().getWidth(), form_elements.getRect().getHeight() - 2 * FORM_PADDING_VERTICAL); + textbox->reshape(textbox->getRect().getWidth(), MIN_NOTIFICATION_AREA_HEIGHT - 2 * FORM_PADDING_VERTICAL); form_elements.addChild(textbox); cur_x = textbox->getRect().mRight + FORM_PADDING_HORIZONTAL; @@ -249,7 +341,7 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params) } } - mFormHeight = form_elements.getRect().getHeight() - (cur_y - FORM_PADDING_VERTICAL) + WIDGET_HEIGHT; + mFormHeight = form_elements.getRect().getHeight() - (cur_y - WIDGET_HEIGHT - FORM_PADDING_VERTICAL); form_elements.reshape(form_width, mFormHeight); form_elements.setMinDim(form_width); @@ -261,68 +353,33 @@ void LLWindowShade::initFromParams(const LLWindowShade::Params& params) { (*it)->translate(0, delta_y); } -} -void LLWindowShade::show() -{ getChildRef<LLLayoutPanel>("notification_area").setVisible(true); getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(mModal); setMouseOpaque(mModal); } -void LLWindowShade::draw() +void LLWindowShade::setBackgroundImage(LLUIImage* image) { - LLRect message_rect = getChild<LLTextBox>("notification_text")->getTextBoundingRect(); - - LLLayoutPanel* notification_area = getChild<LLLayoutPanel>("notification_area"); - - notification_area->reshape(notification_area->getRect().getWidth(), - llclamp(message_rect.getHeight() + 10, - llmin(mFormHeight, MAX_NOTIFICATION_AREA_HEIGHT), - MAX_NOTIFICATION_AREA_HEIGHT)); - - LLUICtrl::draw(); - if (mNotification && !mNotification->isActive()) - { - hide(); - } + getChild<LLLayoutPanel>("notification_area")->setTransparentImage(image); } -void LLWindowShade::hide() +void LLWindowShade::setTextColor(LLColor4 color) { - getChildRef<LLLayoutPanel>("notification_area").setVisible(false); - getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(false); - - setMouseOpaque(false); + getChild<LLTextBox>("notification_text")->setColor(color); } -void LLWindowShade::onCloseNotification() +void LLWindowShade::setCanClose(bool can_close) { - LLNotifications::instance().cancel(mNotification); + getChildView("close_panel")->setVisible(can_close); } -void LLWindowShade::onClickIgnore(LLUICtrl* ctrl) +LLNotificationPtr LLWindowShade::getCurrentNotification() { - bool check = ctrl->getValue().asBoolean(); - if (mNotification && mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN) + if (mNotifications.empty()) { - // question was "show again" so invert value to get "ignore" - check = !check; + return LLNotificationPtr(); } - mNotification->setIgnored(check); -} - -void LLWindowShade::onClickNotificationButton(const std::string& name) -{ - if (!mNotification) return; - - mNotificationResponse[name] = true; - - mNotification->respond(mNotificationResponse); -} - -void LLWindowShade::onEnterNotificationText(LLUICtrl* ctrl, const std::string& name) -{ - mNotificationResponse[name] = ctrl->getValue().asString(); -} + return mNotifications.back(); +}
\ No newline at end of file diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h index 09ffc2cd54..1dcab4e32f 100644 --- a/indra/llui/llwindowshade.h +++ b/indra/llui/llwindowshade.h @@ -36,7 +36,6 @@ class LLWindowShade : public LLUICtrl public: struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { - Mandatory<LLNotificationPtr> notification; Optional<LLUIImage*> bg_image; Optional<LLUIColor> text_color; Optional<bool> modal, @@ -45,11 +44,16 @@ public: Params(); }; - void show(); + void show(LLNotificationPtr); /*virtual*/ void draw(); void hide(); + void setBackgroundImage(LLUIImage* image); + void setTextColor(LLColor4 color); + void setCanClose(bool can_close); private: + void displayLatestNotification(); + LLNotificationPtr getCurrentNotification(); friend class LLUICtrlFactory; LLWindowShade(const Params& p); @@ -60,7 +64,7 @@ private: void onEnterNotificationText(LLUICtrl* ctrl, const std::string& name); void onClickIgnore(LLUICtrl* ctrl); - LLNotificationPtr mNotification; + std::vector<LLNotificationPtr> mNotifications; LLSD mNotificationResponse; bool mModal; S32 mFormHeight; diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 74fa5d350a..7650fe9229 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -133,10 +133,15 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : navigateHome(); } - // FIXME: How do we create a bevel now? -// LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 ); -// mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN ); -// addChild( mBorder ); + LLWindowShade::Params params; + params.name = "notification_shade"; + params.rect = getLocalRect(); + params.follows.flags = FOLLOWS_ALL; + params.modal = true; + + mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params); + + addChild(mWindowShade); } LLMediaCtrl::~LLMediaCtrl() @@ -1092,39 +1097,28 @@ void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response) void LLMediaCtrl::showNotification(LLNotificationPtr notify) { - delete mWindowShade; + LLWindowShade* shade = getChild<LLWindowShade>("notification_shade"); - LLWindowShade::Params params; - params.name = "notification_shade"; - params.rect = getLocalRect(); - params.follows.flags = FOLLOWS_ALL; - params.notification = notify; - params.modal = true; - //HACK: don't hardcode this if (notify->getIcon() == "Popup_Caution") { - params.bg_image.name = "Yellow_Gradient"; - params.text_color = LLColor4::black; + shade->setBackgroundImage(LLUI::getUIImage("Yellow_Gradient")); + shade->setTextColor(LLColor4::black); + shade->setCanClose(true); } - else - //HACK: another one since XUI doesn't support what we need right now - if (notify->getName() == "AuthRequest") + else if (notify->getName() == "AuthRequest") { - params.bg_image.name = "Yellow_Gradient"; - params.text_color = LLColor4::black; - params.can_close = false; + shade->setBackgroundImage(LLUI::getUIImage("Yellow_Gradient")); + shade->setTextColor(LLColor4::black); + shade->setCanClose(false); } else { //HACK: make this a property of the notification itself, "cancellable" - params.can_close = false; - params.text_color.control = "LabelTextColor"; + shade->setCanClose(false); + shade->setTextColor(LLUIColorTable::instance().getColor("LabelTextColor")); } - mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params); - - addChild(mWindowShade); - mWindowShade->show(); + mWindowShade->show(notify); } void LLMediaCtrl::hideNotification() diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 933b40ec79..39c0628cbe 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -1351,7 +1351,6 @@ void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify) LLWindowShade::Params params; params.rect = mMediaRegion->getLocalRect(); params.follows.flags = FOLLOWS_ALL; - params.notification = notify; //HACK: don't hardcode this if (notify->getIcon() == "Popup_Caution") @@ -1369,7 +1368,7 @@ void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify) mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params); mMediaRegion->addChild(mWindowShade); - mWindowShade->show(); + mWindowShade->show(notify); } void LLPanelPrimMediaControls::hideNotification() |