made hints only expire when explicitly responded to, not implicitly after first seeing them

added hint_popup.xml for hint styling
master
Richard Nelson 2010-08-16 15:01:39 -07:00
parent c20bd2dfee
commit 32e4cda7dc
6 changed files with 204 additions and 134 deletions

View File

@ -48,7 +48,6 @@
// static
std::set<std::string> LLFirstUse::sConfigVariables;
std::map<std::string, LLNotificationPtr> LLFirstUse::sNotifications;
// static
void LLFirstUse::addConfigVariable(const std::string& var)
@ -78,21 +77,10 @@ void LLFirstUse::resetFirstUse()
}
}
// static
void LLFirstUse::useOverrideKeys()
{
// Our orientation island uses key overrides to teach vehicle driving
// so don't show this message until you get off OI. JC
if (!gAgent.inPrelude())
{
firstUseNotification("FirstOverrideKeys", true, "FirstOverrideKeys");
}
}
// static
void LLFirstUse::otherAvatarChatFirst(bool enable)
{
firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "nearby_chat_bar").with("direction", "top"));
firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "incoming_chat").with("direction", "right"));
}
// static
@ -143,24 +131,48 @@ void LLFirstUse::receiveLindens(bool enable)
//static
void LLFirstUse::firstUseNotification(const std::string& control_var, bool enable, const std::string& notification_name, LLSD args, LLSD payload)
{
LLNotificationPtr notif = sNotifications[notification_name];
init();
if (enable)
{
if (!notif && gWarningSettings.getBOOL(control_var))
LL_DEBUGS("LLFirstUse") << "Trigger first use notification " << notification_name << LL_ENDL;
// if notification doesn't already exist and this notification hasn't been disabled...
if (gWarningSettings.getBOOL(control_var))
{ // create new notification
sNotifications[notification_name] = LLNotifications::instance().add(LLNotification::Params().name(notification_name).substitutions(args).payload(payload));
gWarningSettings.setBOOL(control_var, FALSE);
LLNotifications::instance().add(LLNotification::Params().name(notification_name).substitutions(args).payload(payload.with("control_var", control_var)));
}
}
else
{ // want to hide notification
if (notif)
{ // cancel existing notification
LLNotifications::instance().cancel(notif);
sNotifications.erase(notification_name);
}
gWarningSettings.setBOOL(control_var, FALSE);
{
LL_DEBUGS("LLFirstUse") << "Disabling first use notification " << notification_name << LL_ENDL;
LLNotifications::instance().cancelByName(notification_name);
}
}
// static
void LLFirstUse::init()
{
static bool initialized = false;
if (!initialized)
{
LLNotifications::instance().getChannel("Hints")->connectChanged(processNotification);
}
initialized = true;
}
//static
bool LLFirstUse::processNotification(const LLSD& notify)
{
if (notify["sigtype"].asString() == "delete")
{
LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
if (notification)
{
// disable any future notifications
gWarningSettings.setBOOL(notification->getPayload()["control_var"], FALSE);
}
}
return false;
}

View File

@ -90,7 +90,6 @@ public:
static void disableFirstUse();
static void resetFirstUse();
static void useOverrideKeys();
static void otherAvatarChatFirst(bool enable = true);
static void sit(bool enable = true);
static void notUsingDestinationGuide(bool enable = true);
@ -103,7 +102,9 @@ public:
protected:
static void firstUseNotification(const std::string& control_var, bool enable, const std::string& notification_name, LLSD args = LLSD(), LLSD payload = LLSD());
static std::set<std::string> sConfigVariables;
static std::map<std::string, boost::shared_ptr<LLNotification> > sNotifications;
static void init();
static bool processNotification(const LLSD& notify);
};
#endif

View File

@ -63,11 +63,21 @@ public:
}
};
struct TargetParams : public LLInitParam::Block<TargetParams>
{
Mandatory<std::string> target;
Mandatory<EPopupDirection, PopupDirections> direction;
TargetParams()
: target("target"),
direction("direction")
{}
};
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Mandatory<LLNotificationPtr> notification;
Optional<std::string> target;
Optional<EPopupDirection, PopupDirections> direction;
Optional<TargetParams> target_params;
Optional<S32> distance;
Optional<LLUIImage*> left_arrow,
up_arrow,
@ -81,34 +91,31 @@ public:
fade_out_time;
Params()
: direction("direction", TOP),
distance("distance", 24),
target("target"),
left_arrow("left_arrow", LLUI::getUIImage("hint_arrow_left")),
up_arrow("up_arrow", LLUI::getUIImage("hint_arrow_up")),
right_arrow("right_arrow", LLUI::getUIImage("hint_arrow_right")),
down_arrow("down_arrow", LLUI::getUIImage("hint_arrow_down")),
left_arrow_offset("left_arrow_offset", 3),
up_arrow_offset("up_arrow_offset", -2),
right_arrow_offset("right_arrow_offset", -3),
down_arrow_offset("down_arrow_offset", 5),
fade_in_time("fade_in_time", 0.2f),
fade_out_time("fade_out_time", 0.5f)
: distance("distance"),
left_arrow("left_arrow"),
up_arrow("up_arrow"),
right_arrow("right_arrow"),
down_arrow("down_arrow"),
left_arrow_offset("left_arrow_offset"),
up_arrow_offset("up_arrow_offset"),
right_arrow_offset("right_arrow_offset"),
down_arrow_offset("down_arrow_offset"),
fade_in_time("fade_in_time"),
fade_out_time("fade_out_time")
{}
};
LLHintPopup(const Params&);
void setHintTarget(LLHandle<LLView> target) { mTarget = target; }
/*virtual*/ BOOL postBuild();
void onClickClose() { hide(); }
void onClickClose() { hide(); LLNotifications::instance().cancel(mNotification); }
void draw();
void hide() { if(!mHidden) {mHidden = true; mFadeTimer.reset();} }
private:
LLNotificationPtr mNotification;
LLHandle<LLView> mTarget;
std::string mTarget;
EPopupDirection mDirection;
S32 mDistance;
LLUIImagePtr mArrowLeft,
@ -125,14 +132,14 @@ private:
bool mHidden;
};
static LLDefaultChildRegistry::Register<LLHintPopup> r("hint_popup");
LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
: mNotification(p.notification),
mDirection(p.direction),
mDirection(p.target_params.direction),
mDistance(p.distance),
mTarget(LLHints::getHintTarget(p.target)),
mTarget(p.target_params.target),
mArrowLeft(p.left_arrow),
mArrowUp(p.up_arrow),
mArrowRight(p.right_arrow),
@ -146,7 +153,7 @@ LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
mFadeOutTime(p.fade_out_time),
LLPanel(p)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_hint.xml");
buildPanel(this, "panel_hint.xml", NULL, p);
}
BOOL LLHintPopup::postBuild()
@ -172,80 +179,108 @@ void LLHintPopup::draw()
if (alpha == 0.f)
{
die();
return;
}
}
else
{
alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeInTime, 0.f, 1.f);
}
LLViewDrawContext context(alpha);
{ LLViewDrawContext context(alpha);
LLView* targetp = mTarget.get();
if (!targetp || !targetp->isInVisibleChain())
{
hide();
}
else
{
LLRect target_rect;
targetp->localRectToOtherView(targetp->getLocalRect(), &target_rect, getParent());
LLRect my_local_rect = getLocalRect();
LLRect my_rect;
LLRect arrow_rect;
LLUIImagePtr arrow_imagep;
switch(mDirection)
if (mTarget.empty())
{
case LEFT:
my_rect.setCenterAndSize( target_rect.mLeft - (my_local_rect.getWidth() / 2 + mDistance),
target_rect.getCenterY(),
my_local_rect.getWidth(),
my_local_rect.getHeight());
arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 + mArrowRightOffset,
my_local_rect.getCenterY(),
mArrowRight->getWidth(),
mArrowRight->getHeight());
arrow_imagep = mArrowRight;
break;
case TOP:
my_rect.setCenterAndSize( target_rect.getCenterX(),
target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance),
my_local_rect.getWidth(),
my_local_rect.getHeight());
arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
my_local_rect.mBottom - mArrowDown->getHeight() / 2 + mArrowDownOffset,
mArrowDown->getWidth(),
mArrowDown->getHeight());
arrow_imagep = mArrowDown;
break;
case RIGHT:
my_rect.setCenterAndSize( target_rect.getCenterX(),
target_rect.mTop - (my_local_rect.getHeight() / 2 + mDistance),
my_local_rect.getWidth(),
my_local_rect.getHeight());
arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + mArrowLeftOffset,
my_local_rect.getCenterY(),
mArrowLeft->getWidth(),
mArrowLeft->getHeight());
arrow_imagep = mArrowLeft;
break;
case BOTTOM:
my_rect.setCenterAndSize( target_rect.getCenterX(),
target_rect.mBottom - (my_local_rect.getHeight() / 2 + mDistance),
my_local_rect.getWidth(),
my_local_rect.getHeight());
arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
my_local_rect.mTop + mArrowUp->getHeight() / 2 + mArrowUpOffset,
mArrowUp->getWidth(),
mArrowUp->getHeight());
arrow_imagep = mArrowUp;
break;
// just draw contents, no arrow, in default position
LLPanel::draw();
}
setShape(my_rect);
LLPanel::draw();
else
{
LLView* targetp = LLHints::getHintTarget(mTarget).get();
if (!targetp)
{
// target widget is no longer valid, go away
die();
}
else if (!targetp->isInVisibleChain())
{
// if target is invisible, don't draw, but keep alive in case widget comes back
}
else
{
LLRect target_rect;
targetp->localRectToOtherView(targetp->getLocalRect(), &target_rect, getParent());
arrow_imagep->draw(arrow_rect, LLColor4(1.f, 1.f, 1.f, alpha));
LLRect my_local_rect = getLocalRect();
LLRect my_rect;
LLRect arrow_rect;
LLUIImagePtr arrow_imagep;
switch(mDirection)
{
case LEFT:
my_rect.setCenterAndSize( target_rect.mLeft - (my_local_rect.getWidth() / 2 + mDistance),
target_rect.getCenterY(),
my_local_rect.getWidth(),
my_local_rect.getHeight());
if (mArrowRight)
{
arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 + mArrowRightOffset,
my_local_rect.getCenterY(),
mArrowRight->getWidth(),
mArrowRight->getHeight());
arrow_imagep = mArrowRight;
}
break;
case TOP:
my_rect.setCenterAndSize( target_rect.getCenterX(),
target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance),
my_local_rect.getWidth(),
my_local_rect.getHeight());
if (mArrowDown)
{
arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
my_local_rect.mBottom - mArrowDown->getHeight() / 2 + mArrowDownOffset,
mArrowDown->getWidth(),
mArrowDown->getHeight());
arrow_imagep = mArrowDown;
}
break;
case RIGHT:
my_rect.setCenterAndSize( target_rect.mRight + (my_local_rect.getWidth() / 2 + mDistance),
target_rect.getCenterY(),
my_local_rect.getWidth(),
my_local_rect.getHeight());
if (mArrowLeft)
{
arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + mArrowLeftOffset,
my_local_rect.getCenterY(),
mArrowLeft->getWidth(),
mArrowLeft->getHeight());
arrow_imagep = mArrowLeft;
}
break;
case BOTTOM:
my_rect.setCenterAndSize( target_rect.getCenterX(),
target_rect.mBottom - (my_local_rect.getHeight() / 2 + mDistance),
my_local_rect.getWidth(),
my_local_rect.getHeight());
if (mArrowUp)
{
arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
my_local_rect.mTop + mArrowUp->getHeight() / 2 + mArrowUpOffset,
mArrowUp->getWidth(),
mArrowUp->getHeight());
arrow_imagep = mArrowUp;
}
break;
}
setShape(my_rect);
LLPanel::draw();
if (arrow_imagep) arrow_imagep->draw(arrow_rect, LLColor4(1.f, 1.f, 1.f, alpha));
}
}
}
}
@ -256,20 +291,23 @@ std::map<LLNotificationPtr, class LLHintPopup*> LLHints::sHints;
//static
void LLHints::show(LLNotificationPtr hint)
{
LLHintPopup::Params p;
LLParamSDParser::instance().readSD(hint->getPayload(), p);
LLHintPopup::Params p(LLUICtrlFactory::getDefaultParams<LLHintPopup>());
LLParamSDParser::instance().readSD(hint->getPayload(), p);
p.notification = hint;
LLHintPopup* popup = new LLHintPopup(p);
sHints[hint] = popup;
LLView* hint_holder = gViewerWindow->getHintHolder();
if (hint_holder)
if (p.validateBlock())
{
hint_holder->addChild(popup);
popup->centerWithin(hint_holder->getLocalRect());
LLHintPopup* popup = new LLHintPopup(p);
sHints[hint] = popup;
LLView* hint_holder = gViewerWindow->getHintHolder();
if (hint_holder)
{
hint_holder->addChild(popup);
popup->centerWithin(hint_holder->getLocalRect());
}
}
}
@ -286,7 +324,7 @@ void LLHints::hide(LLNotificationPtr hint)
//static
void LLHints::registerHintTarget(const std::string& name, LLHandle<LLView> target)
{
sTargetRegistry.defaultRegistrar().add(name, target);
sTargetRegistry.defaultRegistrar().replace(name, target);
}
//static

View File

@ -6402,6 +6402,7 @@ Mute everyone?
label="Chat"
type="hint">
To join the conversation, type into the chat field below.
<unique/>
</notification>
<notification
@ -6409,21 +6410,23 @@ Mute everyone?
label="Stand"
type="hint">
To stand up and exit the sitting position, click the Stand button.
<unique/>
</notification>
<notification
name="HintDestinationGuide"
label="Explore the World"
type="hint">
The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring.
<unique/>
</notification>
<notification
name="HintSidePanel"
label="Side Panel"
type="hint">
Get quick access to your inventory, outfits, profiles and more in the side panel.
<!--<unique/>-->
<unique/>
</notification>
<notification
@ -6431,7 +6434,7 @@ Mute everyone?
label="Move"
type="hint">
To walk or run, open the Move Panel and use the directional arrows to navigate. You can also use the directional keys on your keyboard.
<!--<unique/>-->
<unique/>
</notification>
<notification
@ -6439,6 +6442,7 @@ Mute everyone?
label="Inventory"
type="hint">
Check your inventory to find items. Newest items can be easily found in the Recent tab.
<unique/>
</notification>
<notification
@ -6446,6 +6450,7 @@ Mute everyone?
label="You've got Linden Dollars!"
type="hint">
Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars.
<unique/>
</notification>
<global name="UnsupportedCPU">

View File

@ -1,12 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
name="hint"
width="205"
height="100"
background_opaque="true"
background_visible="true"
layout="topleft"
bg_opaque_image="hint_background">
height="100">
<text name="hint_title"
font="SansSerifMedium"
left="8"
@ -20,7 +15,7 @@
left="8"
right="197"
top="26"
bottom="90"
bottom="92"
follows="all"
text_color="White"
wrap="true"/>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<hint_popup
name="hint"
background_opaque="true"
background_visible="true"
layout="topleft"
bg_opaque_image="hint_background"
distance="24"
left_arrow="hint_arrow_left"
up_arrow="hint_arrow_up"
right_arrow="hint_arrow_right"
down_arrow="hint_arrow_down"
left_arrow_offset="3"
up_arrow_offset="-2"
right_arrow_offset="-3"
down_arrow_offset="5"
fade_in_time="0.2"
fade_out_time="0.3">
</hint_popup>