summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
authorRichard Linden <none@none>2010-12-10 10:11:03 -0800
committerRichard Linden <none@none>2010-12-10 10:11:03 -0800
commit8044661bd581fd7b6a25bd04d4c4f7e32e421faf (patch)
tree5d4a60e2dc914d7016884a8e60fa6ea8b7a118d3 /indra/llui
parent61b675e0afb96d1d46b1f36a8d54bb8146ef27d6 (diff)
WIP XUI HTTP Auth dialog
refactored LLWindowShade into seperate file improved layout of dialog improved dialog resizing logic Tab and Enter keys now work as expected in windowshade form added "modal" capability to window shade added HTTP Auth notifications to MOAP
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/lllayoutstack.h3
-rw-r--r--indra/llui/lluictrl.cpp2
-rw-r--r--indra/llui/llview.h9
-rw-r--r--indra/llui/llwindowshade.cpp328
-rw-r--r--indra/llui/llwindowshade.h69
6 files changed, 405 insertions, 8 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index e98201ea63..063e3906c7 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -111,6 +111,7 @@ set(llui_SOURCE_FILES
llviewmodel.cpp
llview.cpp
llviewquery.cpp
+ llwindowshade.cpp
)
set(llui_HEADER_FILES
@@ -209,6 +210,7 @@ set(llui_HEADER_FILES
llviewmodel.h
llview.h
llviewquery.h
+ llwindowshade.h
)
set_source_files_properties(${llui_HEADER_FILES}
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 9e8539c716..e43669d893 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -173,6 +173,9 @@ public:
~LLLayoutPanel();
void initFromParams(const Params& p);
+ void setMinDim(S32 value) { mMinDim = value; }
+ void setMaxDim(S32 value) { mMaxDim = value; }
+
protected:
LLLayoutPanel(const Params& p) ;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 3ac3bf8c41..d81f425cce 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -823,7 +823,7 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot()
{
LLUICtrl* focus_root = NULL;
LLUICtrl* next_view = this;
- while(next_view)
+ while(next_view && next_view->hasTabStop())
{
if (next_view->isFocusRoot())
{
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 33d345beff..cd2f215c2d 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -412,14 +412,9 @@ public:
LLControlVariable *findControl(const std::string& name);
- // Moved setValue(), getValue(), setControlValue(), setControlName(),
- // controlListener() to LLUICtrl because an LLView is NOT assumed to
- // contain a value. If that's what you want, use LLUICtrl instead.
-// virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
-
const child_list_t* getChildList() const { return &mChildList; }
- const child_list_const_iter_t beginChild() { return mChildList.begin(); }
- const child_list_const_iter_t endChild() { return mChildList.end(); }
+ child_list_const_iter_t beginChild() const { return mChildList.begin(); }
+ child_list_const_iter_t endChild() const { return mChildList.end(); }
// LLMouseHandler functions
// Default behavior is to pass events to children
diff --git a/indra/llui/llwindowshade.cpp b/indra/llui/llwindowshade.cpp
new file mode 100644
index 0000000000..77e94385d4
--- /dev/null
+++ b/indra/llui/llwindowshade.cpp
@@ -0,0 +1,328 @@
+/**
+ * @file LLWindowShade.cpp
+ * @brief Notification dialog that slides down and optionally disabled a piece of UI
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llwindowshade.h"
+
+#include "lllayoutstack.h"
+#include "lltextbox.h"
+#include "lliconctrl.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "lllineeditor.h"
+
+const S32 MIN_NOTIFICATION_AREA_HEIGHT = 30;
+const S32 MAX_NOTIFICATION_AREA_HEIGHT = 100;
+
+LLWindowShade::Params::Params()
+: bg_image("bg_image"),
+ modal("modal", false),
+ text_color("text_color"),
+ can_close("can_close", true)
+{
+ mouse_opaque = false;
+}
+
+LLWindowShade::LLWindowShade(const LLWindowShade::Params& params)
+: LLUICtrl(params),
+ mNotification(params.notification),
+ mModal(params.modal),
+ mFormHeight(0),
+ mTextColor(params.text_color)
+{
+ setFocusRoot(true);
+}
+
+void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
+{
+ LLUICtrl::initFromParams(params);
+
+ LLLayoutStack::Params layout_p;
+ layout_p.name = "notification_stack";
+ layout_p.rect = params.rect;
+ layout_p.follows.flags = FOLLOWS_ALL;
+ layout_p.mouse_opaque = false;
+ layout_p.orientation = LLLayoutStack::VERTICAL;
+ layout_p.border_size = 0;
+
+ LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
+ addChild(stackp);
+
+ LLLayoutPanel::Params panel_p;
+ panel_p.rect = LLRect(0, 30, 800, 0);
+ panel_p.name = "notification_area";
+ panel_p.visible = false;
+ panel_p.user_resize = false;
+ panel_p.background_visible = true;
+ panel_p.bg_alpha_image = params.bg_image;
+ panel_p.auto_resize = false;
+ LLLayoutPanel* notification_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(notification_panel);
+
+ panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+ panel_p.auto_resize = true;
+ panel_p.user_resize = false;
+ panel_p.rect = params.rect;
+ panel_p.name = "background_area";
+ panel_p.mouse_opaque = false;
+ panel_p.background_visible = false;
+ panel_p.bg_alpha_color = LLColor4(0.f, 0.f, 0.f, 0.2f);
+ LLLayoutPanel* dummy_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(dummy_panel);
+
+ layout_p = LLUICtrlFactory::getDefaultParams<LLLayoutStack>();
+ layout_p.rect = LLRect(0, 30, 800, 0);
+ layout_p.follows.flags = FOLLOWS_ALL;
+ layout_p.orientation = LLLayoutStack::HORIZONTAL;
+ stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
+ notification_panel->addChild(stackp);
+
+ panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+ panel_p.rect.height = 30;
+ LLLayoutPanel* panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+ stackp->addChild(panel);
+
+ LLIconCtrl::Params icon_p;
+ icon_p.name = "notification_icon";
+ icon_p.rect = LLRect(5, 23, 21, 8);
+ panel->addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_p));
+
+ LLTextBox::Params text_p;
+ text_p.rect = LLRect(31, 20, panel->getRect().getWidth() - 5, 0);
+ text_p.follows.flags = FOLLOWS_ALL;
+ text_p.text_color = mTextColor;
+ text_p.font = LLFontGL::getFontSansSerifSmall();
+ text_p.font.style = "BOLD";
+ text_p.name = "notification_text";
+ text_p.use_ellipses = true;
+ text_p.wrap = true;
+ panel->addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
+
+ panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+ panel_p.auto_resize = false;
+ panel_p.user_resize = false;
+ panel_p.name="form_elements";
+ panel_p.rect = LLRect(0, 30, 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, 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));
+ }
+
+ LLSD payload = mNotification->getPayload();
+
+ LLNotificationFormPtr formp = mNotification->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());
+
+ LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType();
+ LLLayoutPanel& form_elements = notification_area.getChildRef<LLLayoutPanel>("form_elements");
+ form_elements.deleteAllChildren();
+
+ const S32 FORM_PADDING_HORIZONTAL = 10;
+ const S32 FORM_PADDING_VERTICAL = 3;
+ const S32 WIDGET_HEIGHT = 24;
+ const S32 LINE_EDITOR_WIDTH = 120;
+ S32 cur_x = FORM_PADDING_HORIZONTAL;
+ S32 cur_y = FORM_PADDING_VERTICAL + WIDGET_HEIGHT;
+ S32 form_width = cur_x;
+
+ if (ignore_type != LLNotificationForm::IGNORE_NO)
+ {
+ LLCheckBoxCtrl::Params checkbox_p;
+ checkbox_p.name = "ignore_check";
+ checkbox_p.rect = LLRect(cur_x, cur_y, cur_x, cur_y - WIDGET_HEIGHT);
+ checkbox_p.label = formp->getIgnoreMessage();
+ checkbox_p.label_text.text_color = LLColor4::black;
+ checkbox_p.commit_callback.function = boost::bind(&LLWindowShade::onClickIgnore, this, _1);
+ checkbox_p.initial_value = formp->getIgnored();
+
+ LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(checkbox_p);
+ check->setRect(check->getBoundingRect());
+ form_elements.addChild(check);
+ cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL;
+ form_width = llmax(form_width, cur_x);
+ }
+
+ for (S32 i = 0; i < formp->getNumElements(); i++)
+ {
+ LLSD form_element = formp->getElement(i);
+ std::string type = form_element["type"].asString();
+ if (type == "button")
+ {
+ LLButton::Params button_p;
+ button_p.name = form_element["name"];
+ button_p.label = form_element["text"];
+ button_p.rect = LLRect(cur_x, cur_y, cur_x, cur_y - WIDGET_HEIGHT);
+ button_p.click_callback.function = boost::bind(&LLWindowShade::onClickNotificationButton, this, form_element["name"].asString());
+ button_p.auto_resize = true;
+
+ LLButton* button = LLUICtrlFactory::create<LLButton>(button_p);
+ button->autoResize();
+ form_elements.addChild(button);
+
+ if (form_element["default"].asBoolean())
+ {
+ form_elements.setDefaultBtn(button);
+ }
+
+ cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL;
+ form_width = llmax(form_width, cur_x);
+ }
+ else if (type == "text" || type == "password")
+ {
+ // if not at beginning of line...
+ if (cur_x != FORM_PADDING_HORIZONTAL)
+ {
+ // start new line
+ cur_x = FORM_PADDING_HORIZONTAL;
+ cur_y -= WIDGET_HEIGHT + FORM_PADDING_VERTICAL;
+ }
+ LLTextBox::Params label_p;
+ label_p.name = form_element["name"].asString() + "_label";
+ label_p.rect = LLRect(cur_x, cur_y, cur_x + LINE_EDITOR_WIDTH, cur_y - WIDGET_HEIGHT);
+ label_p.initial_value = form_element["text"];
+ label_p.text_color = mTextColor;
+ label_p.font_valign = LLFontGL::VCENTER;
+ 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);
+ form_elements.addChild(textbox);
+ cur_x = textbox->getRect().mRight + FORM_PADDING_HORIZONTAL;
+
+ LLLineEditor::Params line_p;
+ line_p.name = form_element["name"];
+ line_p.keystroke_callback = boost::bind(&LLWindowShade::onEnterNotificationText, this, _1, form_element["name"].asString());
+ line_p.is_password = type == "password";
+ line_p.rect = LLRect(cur_x, cur_y, cur_x + LINE_EDITOR_WIDTH, cur_y - WIDGET_HEIGHT);
+
+ LLLineEditor* line_editor = LLUICtrlFactory::create<LLLineEditor>(line_p);
+ form_elements.addChild(line_editor);
+ form_width = llmax(form_width, cur_x + LINE_EDITOR_WIDTH + FORM_PADDING_HORIZONTAL);
+
+ // reset to start of next line
+ cur_x = FORM_PADDING_HORIZONTAL;
+ cur_y -= WIDGET_HEIGHT + FORM_PADDING_VERTICAL;
+ }
+ }
+
+ mFormHeight = form_elements.getRect().getHeight() - (cur_y - FORM_PADDING_VERTICAL) + WIDGET_HEIGHT;
+ form_elements.reshape(form_width, mFormHeight);
+ form_elements.setMinDim(form_width);
+
+ // move all form elements back onto form surface
+ S32 delta_y = WIDGET_HEIGHT + FORM_PADDING_VERTICAL - cur_y;
+ for (child_list_const_iter_t it = form_elements.getChildList()->begin(), end_it = form_elements.getChildList()->end();
+ it != end_it;
+ ++it)
+ {
+ (*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()
+{
+ 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();
+ }
+}
+
+void LLWindowShade::hide()
+{
+ getChildRef<LLLayoutPanel>("notification_area").setVisible(false);
+ getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(false);
+
+ setMouseOpaque(false);
+}
+
+void LLWindowShade::onCloseNotification()
+{
+ LLNotifications::instance().cancel(mNotification);
+}
+
+void LLWindowShade::onClickIgnore(LLUICtrl* ctrl)
+{
+ bool check = ctrl->getValue().asBoolean();
+ if (mNotification && mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+ {
+ // question was "show again" so invert value to get "ignore"
+ check = !check;
+ }
+ 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();
+}
diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h
new file mode 100644
index 0000000000..0047195929
--- /dev/null
+++ b/indra/llui/llwindowshade.h
@@ -0,0 +1,69 @@
+/**
+ * @file llwindowshade.h
+ * @brief Notification dialog that slides down and optionally disabled a piece of UI
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLWINDOWSHADE_H
+#define LL_LLWINDOWSHADE_H
+
+#include "lluictrl.h"
+#include "llnotifications.h"
+
+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,
+ can_close;
+
+ Params();
+ };
+
+ void show();
+ /*virtual*/ void draw();
+ void hide();
+
+private:
+ friend class LLUICtrlFactory;
+
+ LLWindowShade(const Params& p);
+ void initFromParams(const Params& params);
+
+ void onCloseNotification();
+ void onClickNotificationButton(const std::string& name);
+ void onEnterNotificationText(LLUICtrl* ctrl, const std::string& name);
+ void onClickIgnore(LLUICtrl* ctrl);
+
+ LLNotificationPtr mNotification;
+ LLSD mNotificationResponse;
+ bool mModal;
+ S32 mFormHeight;
+ LLUIColor mTextColor;
+};
+
+#endif // LL_LLWINDOWSHADE_H