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
meow-7.2.2
Richard Linden 2010-12-10 10:11:03 -08:00
parent 61b675e0af
commit 8044661bd5
15 changed files with 546 additions and 286 deletions

View File

@ -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}

View File

@ -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) ;

View File

@ -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())
{

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -31,6 +31,7 @@
#include "llnotifications.h"
#include "llmediactrl.h"
#include "llviewermedia.h"
#include "llviewermediafocus.h"
using namespace LLNotificationsUI;
@ -39,10 +40,19 @@ bool LLBrowserNotification::processNotification(const LLSD& notify)
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
if (!notification) return false;
LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(notification->getPayload()["media_id"].asUUID());
LLUUID media_id = notification->getPayload()["media_id"].asUUID();
LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);
if (media_instance)
{
media_instance->showNotification(notification);
}
else if (LLViewerMediaFocus::instance().getControlsMediaID() == media_id)
{
LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(media_id);
if (impl)
{
impl->showNotification(notification);
}
}
return false;
}

View File

@ -57,264 +57,12 @@
#include "lllineeditor.h"
#include "llfloatermediabrowser.h"
#include "llfloaterwebcontent.h"
#include "llwindowshade.h"
extern BOOL gRestoreGL;
static LLDefaultChildRegistry::Register<LLMediaCtrl> r("web_browser");
class LLWindowShade : public LLView
{
public:
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
Mandatory<LLNotificationPtr> notification;
Optional<LLUIImage*> bg_image;
Params()
: bg_image("bg_image")
{
mouse_opaque = false;
}
};
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;
};
LLWindowShade::LLWindowShade(const LLWindowShade::Params& params)
: LLView(params),
mNotification(params.notification)
{
}
void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
{
LLView::initFromParams(params);
LLLayoutStack::Params layout_p;
layout_p.name = "notification_stack";
layout_p.rect = LLRect(0,getLocalRect().mTop,getLocalRect().mRight, 30);
layout_p.follows.flags = FOLLOWS_ALL;
layout_p.mouse_opaque = false;
layout_p.orientation = LLLayoutStack::VERTICAL;
LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
addChild(stackp);
LLLayoutPanel::Params panel_p;
panel_p.rect = LLRect(0, 30, 800, 0);
panel_p.min_height = 30;
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.mouse_opaque = false;
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, 430, 0);
text_p.text_color = LLColor4::black;
text_p.font = LLFontGL::getFontSansSerif();
text_p.font.style = "BOLD";
text_p.name = "notification_text";
text_p.use_ellipses = 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);
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=LLUIColorTable::instance().getColor("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;
S32 cur_x = FORM_PADDING_HORIZONTAL;
if (ignore_type != LLNotificationForm::IGNORE_NO)
{
LLCheckBoxCtrl::Params checkbox_p;
checkbox_p.name = "ignore_check";
checkbox_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL);
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;
}
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, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL);
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);
cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL;
}
else if (type == "text" || type == "password")
{
LLTextBox::Params label_p;
label_p.name = form_element["name"].asString() + "_label";
label_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x + 120, FORM_PADDING_VERTICAL);
label_p.initial_value = form_element["text"];
label_p.text_color = LLColor4::black;
LLTextBox* textbox = LLUICtrlFactory::create<LLTextBox>(label_p);
textbox->reshapeToFitText();
form_elements.addChild(textbox);
cur_x = textbox->getRect().mRight + FORM_PADDING_HORIZONTAL;
LLLineEditor::Params line_p;
line_p.name = form_element["name"];
line_p.commit_callback.function = boost::bind(&LLWindowShade::onEnterNotificationText, this, _1, form_element["name"].asString());
line_p.commit_on_focus_lost = true;
line_p.is_password = type == "password";
line_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x + 120, FORM_PADDING_VERTICAL);
LLLineEditor* line_editor = LLUICtrlFactory::create<LLLineEditor>(line_p);
form_elements.addChild(line_editor);
cur_x = line_editor->getRect().mRight + FORM_PADDING_HORIZONTAL;
}
}
form_elements.reshape(cur_x, form_elements.getRect().getHeight());
}
void LLWindowShade::show()
{
LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area");
panel.setVisible(true);
}
void LLWindowShade::draw()
{
LLView::draw();
if (mNotification && !mNotification->isActive())
{
hide();
}
}
void LLWindowShade::hide()
{
LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area");
panel.setVisible(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();
}
LLMediaCtrl::Params::Params()
: start_url("start_url"),
border_visible("border_visible", true),
@ -1305,7 +1053,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
LLNotification::Params auth_request_params;
auth_request_params.name = "AuthRequest";
auth_request_params.payload = LLSD().with("media_id", mMediaTextureID);
auth_request_params.functor.function = boost::bind(&LLMediaCtrl::onAuthSubmit, this, _1, _2);
auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2, mMediaSource->getMediaPlugin());
LLNotifications::instance().add(auth_request_params);
};
break;
@ -1351,31 +1099,27 @@ void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response)
}
}
void LLMediaCtrl::onAuthSubmit(const LLSD& notification, const LLSD& response)
{
if (response["ok"])
{
mMediaSource->getMediaPlugin()->sendAuthResponse(true, response["username"], response["password"]);
}
else
{
mMediaSource->getMediaPlugin()->sendAuthResponse(false, "", "");
}
}
void LLMediaCtrl::showNotification(LLNotificationPtr notify)
{
delete mWindowShade;
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->getName() == "PopupAttempt")
if (notify->getIcon() == "Popup_Caution")
{
params.bg_image.name = "Yellow_Gradient";
params.text_color = LLColor4::black;
}
else
{
//HACK: make this a property of the notification itself, "cancellable"
params.can_close = false;
params.text_color.control = "LabelTextColor";
}
mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);

View File

@ -167,7 +167,6 @@ public:
private:
void onVisibilityChange ( const LLSD& new_visibility );
void onPopup(const LLSD& notification, const LLSD& response);
void onAuthSubmit(const LLSD& notification, const LLSD& response);
const S32 mTextureDepthBytes;
LLUUID mMediaTextureID;

View File

@ -59,6 +59,7 @@
#include "llvovolume.h"
#include "llweb.h"
#include "llwindow.h"
#include "llwindowshade.h"
#include "llfloatertools.h" // to enable hide if build tools are up
// Functions pulled from pipeline.cpp
@ -90,7 +91,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() :
mTargetObjectNormal(LLVector3::zero),
mZoomObjectID(LLUUID::null),
mZoomObjectFace(0),
mVolumeSliderVisible(0)
mVolumeSliderVisible(0),
mWindowShade(NULL)
{
mCommitCallbackRegistrar.add("MediaCtrl.Close", boost::bind(&LLPanelPrimMediaControls::onClickClose, this));
mCommitCallbackRegistrar.add("MediaCtrl.Back", boost::bind(&LLPanelPrimMediaControls::onClickBack, this));
@ -205,6 +207,9 @@ BOOL LLPanelPrimMediaControls::postBuild()
mMediaAddress->setFocusReceivedCallback(boost::bind(&LLPanelPrimMediaControls::onInputURL, _1, this ));
LLWindowShade::Params window_shade_params;
window_shade_params.name = "window_shade";
mCurrentZoom = ZOOM_NONE;
// clicks on buttons do not remove keyboard focus from media
setIsChrome(TRUE);
@ -698,6 +703,24 @@ void LLPanelPrimMediaControls::updateShape()
/*virtual*/
void LLPanelPrimMediaControls::draw()
{
LLViewerMediaImpl* impl = getTargetMediaImpl();
if (impl)
{
LLNotificationPtr notification = impl->getCurrentNotification();
if (notification != mActiveNotification)
{
mActiveNotification = notification;
if (notification)
{
showNotification(notification);
}
else
{
hideNotification();
}
}
}
F32 alpha = getDrawContext().mAlpha;
if(mFadeTimer.getStarted())
{
@ -1295,3 +1318,38 @@ bool LLPanelPrimMediaControls::shouldVolumeSliderBeVisible()
{
return mVolumeSliderVisible > 0;
}
void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify)
{
delete mWindowShade;
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")
{
params.bg_image.name = "Yellow_Gradient";
params.text_color = LLColor4::black;
}
else
{
//HACK: make this a property of the notification itself, "cancellable"
params.can_close = false;
params.text_color.control = "LabelTextColor";
}
mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
mMediaRegion->addChild(mWindowShade);
mWindowShade->show();
}
void LLPanelPrimMediaControls::hideNotification()
{
if (mWindowShade)
{
mWindowShade->hide();
}
}

View File

@ -29,6 +29,7 @@
#include "llpanel.h"
#include "llviewermedia.h"
#include "llnotificationptr.h"
class LLButton;
class LLCoordWindow;
@ -37,6 +38,7 @@ class LLLayoutStack;
class LLProgressBar;
class LLSliderCtrl;
class LLViewerMediaImpl;
class LLWindowShade;
class LLPanelPrimMediaControls : public LLPanel
{
@ -54,6 +56,9 @@ public:
void updateShape();
bool isMouseOver();
void showNotification(LLNotificationPtr notify);
void hideNotification();
enum EZoomLevel
{
ZOOM_NONE = 0,
@ -162,6 +167,7 @@ private:
LLUICtrl *mRightBookend;
LLUIImage* mBackgroundImage;
LLUIImage* mVolumeSliderBackgroundImage;
LLWindowShade* mWindowShade;
F32 mSkipStep;
S32 mMinWidth;
S32 mMinHeight;
@ -204,6 +210,8 @@ private:
S32 mZoomObjectFace;
S32 mVolumeSliderVisible;
LLNotificationPtr mActiveNotification;
};
#endif // LL_PANELPRIMMEDIACONTROLS_H

View File

@ -52,6 +52,7 @@
#include "llviewerregion.h"
#include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this!
#include "llfilepicker.h"
#include "llnotifications.h"
#include "llevent.h" // LLSimpleListener
#include "llnotificationsutil.h"
@ -1044,6 +1045,18 @@ bool LLViewerMedia::isParcelAudioPlaying()
return (LLViewerMedia::hasParcelAudio() && gAudiop && LLAudioEngine::AUDIO_PLAYING == gAudiop->isInternetStreamPlaying());
}
void LLViewerMedia::onAuthSubmit(const LLSD& notification, const LLSD& response, LLPluginClassMedia* media)
{
if (response["ok"])
{
media->sendAuthResponse(true, response["username"], response["password"]);
}
else
{
media->sendAuthResponse(false, "", "");
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::clearAllCookies()
@ -1912,6 +1925,18 @@ void LLViewerMediaImpl::setSize(int width, int height)
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::showNotification(LLNotificationPtr notify)
{
mNotification = notify;
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::hideNotification()
{
mNotification.reset();
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLViewerMediaImpl::play()
{
@ -2976,6 +3001,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN:
{
LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL;
hideNotification();
if(getNavState() == MEDIANAVSTATE_SERVER_SENT)
{
@ -3067,13 +3093,17 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
}
break;
case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:
{
llinfos << "MEDIA_EVENT_AUTH_REQUEST, url " << plugin->getAuthURL() << ", realm " << plugin->getAuthRealm() << LL_ENDL;
//plugin->sendAuthResponse(false, "", "");
}
LLNotification::Params auth_request_params;
auth_request_params.name = "AuthRequest";
auth_request_params.payload = LLSD().with("media_id", mTextureId);
auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2, plugin);
LLNotifications::instance().add(auth_request_params);
};
break;
case LLViewerMediaObserver::MEDIA_EVENT_CLOSE_REQUEST:
{
std::string uuid = plugin->getClickUUID();
@ -3591,6 +3621,11 @@ bool LLViewerMediaImpl::isInAgentParcel() const
return result;
}
LLNotificationPtr LLViewerMediaImpl::getCurrentNotification() const
{
return mNotification;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
// static

View File

@ -37,6 +37,7 @@
#include "llpluginclassmedia.h"
#include "v4color.h"
#include "llnotificationptr.h"
#include "llurl.h"
@ -130,6 +131,8 @@ public:
static bool isParcelMediaPlaying();
static bool isParcelAudioPlaying();
static void onAuthSubmit(const LLSD& notification, const LLSD& response, LLPluginClassMedia* media);
// Clear all cookies for all plugins
static void clearAllCookies();
@ -199,6 +202,9 @@ public:
LLPluginClassMedia* getMediaPlugin() { return mMediaSource; }
void setSize(int width, int height);
void showNotification(LLNotificationPtr notify);
void hideNotification();
void play();
void stop();
void pause();
@ -391,6 +397,9 @@ public:
// Is this media in the agent's parcel?
bool isInAgentParcel() const;
// get currently active notification associated with this media instance
LLNotificationPtr getCurrentNotification() const;
private:
bool isAutoPlayable() const;
bool shouldShowBasedOnClass() const;
@ -448,7 +457,8 @@ private:
bool mNavigateSuspendedDeferred;
bool mTrustedBrowser;
std::string mTarget;
LLNotificationPtr mNotification;
private:
BOOL mIsUpdated ;
std::list< LLVOVolume* > mObjectList ;

View File

@ -592,4 +592,4 @@ LLUUID LLViewerMediaFocus::getControlsMediaID()
}
return LLUUID::null;
}
}

View File

@ -189,7 +189,6 @@
function="Advanced.WebContentTest"
parameter="http://www.google.com"/>
</menu_item_call>
<menu_item_separator/>
<menu_item_check
label="Show Grid Picker"
name="Show Grid Picker"