diff options
-rw-r--r-- | indra/newview/app_settings/settings.xml | 12 | ||||
-rw-r--r-- | indra/newview/lltoastnotifypanel.cpp | 228 | ||||
-rw-r--r-- | indra/newview/lltoastnotifypanel.h | 7 |
3 files changed, 149 insertions, 98 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9c4c8387a8..d0bbcc222d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5062,6 +5062,18 @@ <key>Value</key> <integer>5</integer> </map> + <key>ToastButtonWidth</key> + <map> + <key>Comment</key> + <string>Default width of buttons in the toast. + Note if required width will be less then this one, a button will be reshaped to default size , otherwise to required</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>90</integer> + </map> <key>ChannelBottomPanelMargin</key> <map> <key>Comment</key> diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index d0c125eb77..94acb2ae8c 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -45,7 +45,7 @@ #include "lltrans.h" const S32 BOTTOM_PAD = VPAD * 3; -const S32 BUTTON_WIDTH = 90; +S32 BUTTON_WIDTH = 90; //static const LLFontGL* LLToastNotifyPanel::sFont = NULL; @@ -63,7 +63,7 @@ mAddedDefaultBtn(false) LLUICtrlFactory::getInstance()->buildPanel(this, "panel_notification.xml"); mInfoPanel = getChild<LLPanel>("info_panel"); mControlPanel = getChild<LLPanel>("control_panel"); - + BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth"); // customize panel's attributes // is it intended for displaying a tip mIsTip = notification->getType() == "notifytip"; @@ -96,7 +96,8 @@ mAddedDefaultBtn(false) // customize panel's outfit // preliminary adjust panel's layout - mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form); + //move to the end + //mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form); // adjust text options according to the notification type // add a caution textbox at the top of a caution notification @@ -117,8 +118,14 @@ mAddedDefaultBtn(false) mTextBox->setValue(notification->getMessage()); // add buttons for a script notification - if (!mIsTip) + if (mIsTip) + { + adjustPanelForTipNotice(); + } + else { + std::vector<index_button_pair_t> buttons; + buttons.reserve(mNumOptions); for (S32 i = 0; i < mNumOptions; i++) { LLSD form_element = form->getElement(i); @@ -126,65 +133,155 @@ mAddedDefaultBtn(false) { continue; } - - addButton(form_element["name"].asString(), form_element["text"].asString(), TRUE, form_element["default"].asBoolean()); } - - if (mNumButtons == 0) + S32 buttons_width = 0; + // create all buttons and accumulate they total width to reshape mControlPanel + for (S32 i = 0; i < mNumOptions; i++) { - addButton("OK", LLTrans::getString("ok"), FALSE, TRUE); - mAddedDefaultBtn = true; + LLSD form_element = form->getElement(i); + if (form_element["type"].asString() != "button") + { + continue; + } + LLButton* new_button = createButton(form_element, TRUE); + buttons_width += new_button->getRect().getWidth(); + S32 index = form_element["index"].asInteger(); + buttons.push_back(index_button_pair_t(index,new_button)); + } + if (buttons.empty()) + { + addDefaultButton(); + } + else + { + //try get an average left_pad to spread out buttons + S32 left_pad = (getRect().getWidth() - buttons_width) / (S32(buttons.size() + 1)); + // left_pad can be < 2*HPAD if we have a lot of buttons. + if(left_pad < 2*HPAD) + { + //Probably it is a scriptdialog toast, set default left_pad + left_pad = 2*HPAD; + } + //how many rows we need to fit all buttons with current width of the panel + S32 button_rows = (buttons_width + left_pad * S32(buttons.size() + 1)) / getRect().getWidth() + 1; + //calculate required panel height + S32 button_panel_height = button_rows *( BTN_HEIGHT + VPAD) + BOTTOM_PAD; + + adjustPanelForScriptNotice(getRect().getWidth(), button_panel_height); + //we begin from lefttop angle and go to rightbottom. + updateButtonsLayout(buttons, left_pad, button_panel_height); } } - // adjust panel's height to the text size mInfoPanel->setFollowsAll(); snapToMessageHeight(mTextBox, MAX_LENGTH); } - -LLToastNotifyPanel::~LLToastNotifyPanel() +void LLToastNotifyPanel::addDefaultButton() { - std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); + LLSD form_element; + form_element.with("name", "OK").with("text", LLTrans::getString("ok")).with("default", true); + LLButton* ok_btn = createButton(form_element, FALSE); + LLRect new_btn_rect(ok_btn->getRect()); + + new_btn_rect.setOriginAndSize(llabs(getRect().getWidth() - BUTTON_WIDTH)/ 2, BOTTOM_PAD, + //auto_size for ok button makes it very small, so let's make it wider + BUTTON_WIDTH, new_btn_rect.getHeight()); + ok_btn->setRect(new_btn_rect); + addChild(ok_btn, -1); + mNumButtons = 1; + mAddedDefaultBtn = true; } +LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_option) +{ + InstanceAndS32* userdata = new InstanceAndS32; + userdata->mSelf = this; + userdata->mButtonName = is_option ? form_element["name"].asString() : ""; -void LLToastNotifyPanel::adjustPanelForScriptNotice(const LLNotificationFormPtr form) -{ - F32 buttons_num = 0; - S32 button_rows = 0; + mBtnCallbackData.push_back(userdata); - // calculate number of buttons - for (S32 i = 0; i < mNumOptions; i++) + LLButton::Params p; + const LLFontGL* font = form_element["index"].asInteger() == -1 ? sFontSmall: sFont; // for ignore button in script dialog + p.name(form_element["name"].asString()); + p.label(form_element["text"].asString()); + p.font(font); + p.rect.height = BTN_HEIGHT; + p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); + p.rect.width = BUTTON_WIDTH; + p.auto_resize = false; + p.follows.flags(FOLLOWS_RIGHT | FOLLOWS_LEFT | FOLLOWS_BOTTOM); + if (mIsCaution) { - if (form->getElement(i)["type"].asString() == "button") - { - buttons_num++; - } + p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); + p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); } - - // calculate necessary height for the button panel - // if notification form contains no buttons - reserve a place for OK button - // script notifications have extra line for an IGNORE button - if(mIsScriptDialog) + if (!mIsScriptDialog && font->getWidth(form_element["text"].asString()) > BUTTON_WIDTH) { - button_rows = llceil((buttons_num - 1) / 3.0f) + 1; + p.rect.width = 1; + p.auto_resize = true; } - else + + LLButton* btn = LLUICtrlFactory::create<LLButton>(p); + mNumButtons++; + btn->autoResize(); + if (form_element["default"].asBoolean()) { - button_rows = llmax( 1, llceil(buttons_num / 3.0f)); + setDefaultBtn(btn); } - S32 button_panel_height = button_rows * BTN_HEIGHT + (button_rows + 1) * VPAD + BOTTOM_PAD; + return btn; +} + +LLToastNotifyPanel::~LLToastNotifyPanel() +{ + std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); +} +void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair_t>& buttons, S32 left_pad, S32 top) +{ + S32 left = left_pad; + LLButton* ignore_btn = NULL; + for (std::vector<index_button_pair_t>::const_iterator it = buttons.begin(); it != buttons.end(); it++) + { + if(left + it->second->getRect().getWidth() + 2*HPAD > getRect().getWidth()) + { + // looks like we need to add button to the next row + left = left_pad; + top-= (BTN_HEIGHT + VPAD); + } + LLRect btn_rect(it->second->getRect()); + if(mIsScriptDialog && it->first == -1) + { + //this is ignore button ( index == -1) we need to add it into new extra row at the end + ignore_btn = it->second; + continue; + } + btn_rect.setLeftTopAndSize(left, top, btn_rect.getWidth(), btn_rect.getHeight()); + it->second->setRect(btn_rect); + left = btn_rect.mLeft + btn_rect.getWidth() + left_pad; + addChild(it->second, -1); + } + if(ignore_btn) + { + LLRect btn_rect(ignore_btn->getRect()); + btn_rect.setOriginAndSize(getRect().getWidth() - btn_rect.getWidth() - left_pad, + BOTTOM_PAD,// move button at the bottom edge + btn_rect.getWidth(), btn_rect.getHeight()); + ignore_btn->setRect(btn_rect); + addChild(ignore_btn, -1); + } +} +void LLToastNotifyPanel::adjustPanelForScriptNotice(S32 button_panel_width, S32 button_panel_height) +{ //adjust layout + // we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed LLRect button_rect = mControlPanel->getRect(); - reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight() + button_panel_height); + reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight() + button_panel_height + VPAD); button_rect.set(0, button_rect.mBottom + button_panel_height, button_rect.getWidth(), button_rect.mBottom); mControlPanel->reshape(button_rect.getWidth(), button_panel_height); mControlPanel->setRect(button_rect); } -// static void LLToastNotifyPanel::adjustPanelForTipNotice() { LLRect info_rect = mInfoPanel->getRect(); @@ -208,64 +305,3 @@ void LLToastNotifyPanel::onClickButton(void* data) } self->mNotification->respond(response); } - -// virtual -LLButton* LLToastNotifyPanel::addButton(const std::string& name, const std::string& label, BOOL is_option, BOOL is_default) -{ - LLRect btn_rect; - LLButton* btn; - S32 btn_height= BTN_HEIGHT; - const LLFontGL* font = sFont; - S32 ignore_pad = 0; - S32 button_index = mNumButtons; - S32 index = button_index; - S32 x = HPAD * 2; // *2 - to make a nice offset - - if (mIsScriptDialog) - { - // Add two "blank" option spaces, before the "Ignore" button - index = button_index + 2; - if (button_index == 0) - { - // Ignore button is smaller, less wide - btn_height = BTN_HEIGHT_SMALL; - font = sFontSmall; - ignore_pad = 10; - } - } - - btn_rect.setOriginAndSize(x + (index % 3) * (BUTTON_WIDTH+HPAD+HPAD) + ignore_pad, - BOTTOM_PAD + (index / 3) * (BTN_HEIGHT+VPAD), - BUTTON_WIDTH - 2*ignore_pad, - btn_height); - - InstanceAndS32* userdata = new InstanceAndS32; - userdata->mSelf = this; - userdata->mButtonName = is_option ? name : ""; - - mBtnCallbackData.push_back(userdata); - - LLButton::Params p; - p.name(name); - p.label(label); - p.rect(btn_rect); - p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); - p.font(font); - if (mIsCaution) - { - p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); - p.image_color_disabled(LLUIColorTable::instance().getColor("ButtonCautionImageColor")); - } - btn = LLUICtrlFactory::create<LLButton>(p); - - - mControlPanel->addChild(btn, -1); - - if (is_default) - { - setDefaultBtn(btn); - } - - mNumButtons++; - return btn; -} diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index 04525387b3..1f50c21f6f 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -57,7 +57,7 @@ public: virtual ~LLToastNotifyPanel(); protected: - LLButton* addButton(std::string const &name, const std::string& label, BOOL is_option, BOOL is_default); + LLButton* createButton(const LLSD& form_element, BOOL is_option); // Used for callbacks struct InstanceAndS32 @@ -69,8 +69,11 @@ protected: private: - void adjustPanelForScriptNotice(const boost::shared_ptr<LLNotificationForm> form); + typedef std::pair<int,LLButton*> index_button_pair_t; + void adjustPanelForScriptNotice(S32 max_width, S32 max_height); void adjustPanelForTipNotice(); + void addDefaultButton(); + void updateButtonsLayout(const std::vector<index_button_pair_t>& buttons, S32 left_pad, S32 top); // panel elements LLTextBase* mTextBox; |