summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/app_settings/settings.xml12
-rw-r--r--indra/newview/lltoastnotifypanel.cpp228
-rw-r--r--indra/newview/lltoastnotifypanel.h7
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;