Newer
Older
* @file llchiclet.h
* @brief LLChiclet class header file
*
* $LicenseInfo:firstyear=2002&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_LLCHICLET_H
#define LL_LLCHICLET_H
James Cook
committed
#include "llbutton.h"
maksymsproductengine
committed
#include "llnotifications.h"
#include "lltextbox.h"
AlexanderP ProductEngine
committed
class LLFloaterIMSession;
maksymsproductengine
committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
* Class for displaying amount of messages/notifications(unread).
*/
class LLChicletNotificationCounterCtrl : public LLTextBox
{
public:
struct Params : public LLInitParam::Block<Params, LLTextBox::Params>
{
/**
* Contains maximum displayed count of unread messages. Default value is 9.
*
* If count is less than "max_unread_count" will be displayed as is.
* Otherwise 9+ will be shown (for default value).
*/
Optional<S32> max_displayed_count;
Params();
};
/**
* Sets number of notifications
*/
virtual void setCounter(S32 counter);
/**
* Returns number of notifications
*/
virtual S32 getCounter() const { return mCounter; }
/**
* Returns width, required to display amount of notifications in text form.
* Width is the only valid value.
*/
/*virtual*/ LLRect getRequiredRect();
/**
* Sets number of notifications using LLSD
*/
/*virtual*/ void setValue(const LLSD& value);
/**
* Returns number of notifications wrapped in LLSD
*/
/*virtual*/ LLSD getValue() const;
protected:
LLChicletNotificationCounterCtrl(const Params& p);
friend class LLUICtrlFactory;
private:
S32 mCounter;
S32 mInitialWidth;
S32 mMaxDisplayedCount;
};
class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
{
public:
struct Params : public LLInitParam::Block<Params, LLAvatarIconCtrl::Params>
{
Params()
{
changeDefault(draw_tooltip, FALSE);
changeDefault(mouse_opaque, FALSE);
changeDefault(default_icon_name, "Generic_Person");
};
};
protected:
LLChicletAvatarIconCtrl(const Params& p);
friend class LLUICtrlFactory;
};
Eugene Mutavchi
committed
/**
* Class for displaying icon in inventory offer chiclet.
*/
class LLChicletInvOfferIconCtrl : public LLChicletAvatarIconCtrl
{
public:
struct Params :
public LLInitParam::Block<Params, LLChicletAvatarIconCtrl::Params>
{
Optional<std::string> default_icon;
Params()
: default_icon("default_icon", "Generic_Object_Small")
Eugene Mutavchi
committed
{
changeDefault(avatar_id, LLUUID::null);
Eugene Mutavchi
committed
};
};
/**
* Sets icon, if value is LLUUID::null - default icon will be set.
*/
virtual void setValue(const LLSD& value );
protected:
LLChicletInvOfferIconCtrl(const Params& p);
friend class LLUICtrlFactory;
private:
std::string mDefaultIcon;
};
class LLChiclet : public LLUICtrl
{
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Dmitry Zaporozhan
committed
Optional<bool> show_counter,
enable_counter;
maksymsproductengine
committed
virtual ~LLChiclet() {}
virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; }
virtual const LLUUID& getSessionId() const { return mSessionId; }
maksymsproductengine
committed
/**
* Sets show counter state.
*/
virtual void setShowCounter(bool show) { mShowCounter = show; }
/*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
const commit_callback_t& cb);
typedef boost::function<void (LLChiclet* ctrl, const LLSD& param)>
chiclet_size_changed_callback_t;
virtual boost::signals2::connection setChicletSizeChangedCallback(
const chiclet_size_changed_callback_t& cb);
protected:
friend class LLUICtrlFactory;
LLChiclet(const Params& p);
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual void onChicletSizeChanged();
private:
LLUUID mSessionId;
bool mShowCounter;
typedef boost::signals2::signal<void (LLChiclet* ctrl, const LLSD& param)>
chiclet_size_changed_signal_t;
chiclet_size_changed_signal_t mChicletSizeChangedSignal;
/**
* Base class for Instant Message chiclets.
* IMChiclet displays icon, number of unread messages(optional)
* and voice chat status(optional).
*/
Steven Bennetts
committed
enum EType {
TYPE_UNKNOWN,
TYPE_IM,
Steven Bennetts
committed
};
Dmitry Oleshko
committed
struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
Dmitry Oleshko
committed
virtual ~LLIMChiclet() {};
Denis Serdjuk
committed
/**
* It is used for default setting up of chicklet:click handler, etc.
*/
BOOL postBuild();
maksymsproductengine
committed
/**
* Sets IM session name. This name will be displayed in chiclet tooltip.
*/
virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
/**
* Sets id of person/group user is chatting with.
* Session id should be set before calling this
*/
virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
/**
* Enables/disables the counter control for a chiclet.
*/
virtual void enableCounterControl(bool enable);
/**
* Sets required width for a chiclet according to visible controls.
*/
virtual void setRequiredWidth();
/**
* Shows/hides overlay icon concerning new unread messages.
*/
Dmitry Oleshko
committed
virtual void setShowNewMessagesIcon(bool show);
/**
* Returns visibility of overlay icon concerning new unread messages.
*/
Dmitry Oleshko
committed
virtual bool getShowNewMessagesIcon();
/**
* The action taken on mouse down event.
*
* Made public so that it can be triggered from outside
* (more specifically, from the Active IM window).
*/
Dmitry Zaporozhan
committed
virtual void onMouseDown();
Dmitry Zaporozhan
committed
virtual void setToggleState(bool toggle);
Eugene Mutavchi
committed
/**
* Displays popup menu.
*/
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
Mnikolenko ProductEngine
committed
void hidePopupMenu();
protected:
Dmitry Oleshko
committed
LLIMChiclet(const LLIMChiclet::Params& p);
protected:
Eugene Mutavchi
committed
/**
* Creates chiclet popup menu.
*/
virtual void createPopupMenu() = 0;
/**
* Enables/disables menus.
*/
virtual void updateMenuItems() {};
bool canCreateMenu();
LLMenuGL* mPopupMenu;
bool mShowSpeaker;
bool mCounterEnabled;
Dmitry Zaporozhan
committed
/* initial width of chiclet, should not include counter or speaker width */
S32 mDefaultWidth;
Dmitry Oleshko
committed
LLIconCtrl* mNewMessagesIcon;
Dmitry Zaporozhan
committed
LLButton* mChicletButton;
Dmitry Oleshko
committed
/** the id of another participant, either an avatar id or a group id*/
LLUUID mOtherParticipantId;
template<typename Container>
struct CollectChicletCombiner {
typedef Container result_type;
template<typename InputIterator>
Container operator()(InputIterator first, InputIterator last) const {
Container c = Container();
for (InputIterator iter = first; iter != last; iter++) {
if (*iter != NULL) {
c.push_back(*iter);
}
}
return c;
}
};
public:
static boost::signals2::signal<LLChiclet* (const LLUUID&),
CollectChicletCombiner<std::list<LLChiclet*> > >
sFindChicletsSignal;
Dmitry Zaporozhan
committed
/**
* Chiclet for script floaters.
*/
Dmitry Zaporozhan
committed
class LLScriptChiclet : public LLIMChiclet
{
public:
struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
{
Dmitry Zaporozhan
committed
Optional<LLButton::Params> chiclet_button;
Dmitry Zaporozhan
committed
Optional<LLIconCtrl::Params> icon;
Dmitry Zaporozhan
committed
Dmitry Zaporozhan
committed
Optional<LLIconCtrl::Params> new_message_icon;
Dmitry Zaporozhan
committed
Params();
};
Dmitry Zaporozhan
committed
/*virtual*/ void setSessionId(const LLUUID& session_id);
Dmitry Zaporozhan
committed
Dmitry Zaporozhan
committed
/**
* Toggle script floater
*/
/*virtual*/ void onMouseDown();
Dmitry Zaporozhan
committed
protected:
LLScriptChiclet(const Params&);
friend class LLUICtrlFactory;
Eugene Mutavchi
committed
/**
* Creates chiclet popup menu.
*/
virtual void createPopupMenu();
/**
* Processes clicks on chiclet popup menu.
*/
virtual void onMenuItemClicked(const LLSD& user_data);
Dmitry Zaporozhan
committed
private:
Dmitry Zaporozhan
committed
LLIconCtrl* mChicletIconCtrl;
Dmitry Zaporozhan
committed
};
Eugene Mutavchi
committed
/**
* Chiclet for inventory offer script floaters.
*/
class LLInvOfferChiclet: public LLIMChiclet
{
public:
struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
{
Dmitry Zaporozhan
committed
Optional<LLButton::Params> chiclet_button;
Eugene Mutavchi
committed
Optional<LLChicletInvOfferIconCtrl::Params> icon;
Dmitry Zaporozhan
committed
Optional<LLIconCtrl::Params> new_message_icon;
Eugene Mutavchi
committed
Params();
};
/*virtual*/ void setSessionId(const LLUUID& session_id);
/**
* Toggle script floater
*/
/*virtual*/ void onMouseDown();
protected:
LLInvOfferChiclet(const Params&);
friend class LLUICtrlFactory;
Eugene Mutavchi
committed
/**
* Creates chiclet popup menu.
*/
virtual void createPopupMenu();
/**
* Processes clicks on chiclet popup menu.
*/
virtual void onMenuItemClicked(const LLSD& user_data);
Eugene Mutavchi
committed
private:
LLChicletInvOfferIconCtrl* mChicletIconCtrl;
};
maksymsproductengine
committed
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
/**
* Implements notification chiclet. Used to display total amount of unread messages
* across all IM sessions, total amount of system notifications. See EXT-3147 for details
*/
class LLSysWellChiclet : public LLChiclet
{
public:
struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
{
Optional<LLButton::Params> button;
Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
/**
* Contains maximum displayed count of unread messages. Default value is 9.
*
* If count is less than "max_unread_count" will be displayed as is.
* Otherwise 9+ will be shown (for default value).
*/
Optional<S32> max_displayed_count;
Params();
};
/*virtual*/ void setCounter(S32 counter);
// *TODO: mantipov: seems getCounter is not necessary for LLNotificationChiclet
// but inherited interface requires it to implement.
// Probably it can be safe removed.
/*virtual*/S32 getCounter() { return mCounter; }
boost::signals2::connection setClickCallback(const commit_callback_t& cb);
/*virtual*/ ~LLSysWellChiclet();
void setToggleState(BOOL toggled);
void setNewMessagesState(bool new_messages);
//this method should change a widget according to state of the SysWellWindow
virtual void updateWidget(bool is_window_empty);
protected:
LLSysWellChiclet(const Params& p);
friend class LLUICtrlFactory;
/**
* Change Well 'Lit' state from 'Lit' to 'Unlit' and vice-versa.
*
* There is an assumption that it will be called 2*N times to do not change its start state.
* @see FlashToLitTimer
*/
void changeLitState(bool blink);
/**
* Displays menu.
*/
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual void createMenu() = 0;
protected:
class FlashToLitTimer;
LLButton* mButton;
S32 mCounter;
S32 mMaxDisplayedCount;
bool mIsNewMessagesState;
LLFlashTimer* mFlashToLitTimer;
LLContextMenu* mContextMenu;
};
class LLNotificationChiclet : public LLSysWellChiclet
{
LOG_CLASS(LLNotificationChiclet);
friend class LLUICtrlFactory;
public:
struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
protected:
struct ChicletNotificationChannel : public LLNotificationChannel
{
ChicletNotificationChannel(LLNotificationChiclet* chiclet)
: LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString()))
, mChiclet(chiclet)
{
// connect counter handlers to the signals
connectToChannel("Group Notifications");
connectToChannel("Offer");
connectToChannel("Notifications");
}
static bool filterNotification(LLNotificationPtr notify);
// connect counter updaters to the corresponding signals
/*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
Mnikolenko Productengine
committed
/*virtual*/ void onLoad(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
maksymsproductengine
committed
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
/*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
LLNotificationChiclet* const mChiclet;
};
boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
LLNotificationChiclet(const Params& p);
/**
* Processes clicks on chiclet menu.
*/
void onMenuItemClicked(const LLSD& user_data);
/**
* Enables chiclet menu items.
*/
bool enableMenuItem(const LLSD& user_data);
/**
* Creates menu.
*/
/*virtual*/ void createMenu();
/*virtual*/ void setCounter(S32 counter);
S32 mUreadSystemNotifications;
};
* Storage class for all IM chiclets. Provides mechanism to display,
* scroll, create, remove chiclets.
class LLChicletPanel : public LLPanel
{
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Dmitry Zaporozhan
committed
scrolling_offset,
scroll_button_hpad,
scroll_ratio;
* Creates chiclet and adds it to chiclet list at specified index.
template<class T> T* createChiclet(const LLUUID& session_id, S32 index);
* Creates chiclet and adds it to chiclet list at right.
template<class T> T* createChiclet(const LLUUID& session_id);
* Returns pointer to chiclet of specified type at specified index.
LLChiclet* getChiclet(S32 index) { return getChiclet<LLChiclet>(index); }
template<class T> T* findChiclet(const LLUUID& im_session_id);
void removeAll();
* Scrolls the panel to the specified chiclet
*/
void scrollToChiclet(const LLChiclet* chiclet);
const commit_callback_t& cb);
James Cook
committed
/*virtual*/ BOOL postBuild();
/**
* Handler for the Voice Client's signal. Finds a corresponding chiclet and toggles its SpeakerControl
*/
Dmitry Oleshko
committed
void onCurrentVoiceChannelChanged(const LLUUID& session_id);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
S32 getMinWidth() const { return mMinWidth; }
maksymsproductengine
committed
/*virtual*/ S32 notifyParent(const LLSD& info);
Yuri Chebotarev
committed
Dmitry Zaporozhan
committed
/**
* Toggle chiclet by session id ON and toggle OFF all other chiclets.
*/
void setChicletToggleState(const LLUUID& session_id, bool toggle);
protected:
LLChicletPanel(const Params&p);
friend class LLUICtrlFactory;
Mike Antipov
committed
/**
* Adds chiclet to list and rearranges all chiclets.
* They should be right aligned, most recent right. See EXT-1293
*
* It calculates position of the first chiclet in the list. Other chiclets are placed in arrange().
*
* @see arrange()
*/
Mike Antipov
committed
/**
* Arranges chiclets to have them in correct positions.
*
* Method bases on assumption that first chiclet has correct rect and starts from the its position.
*
* @see addChiclet()
*/
bool canScrollRight();
Yuri Chebotarev
committed
/**
* Returns true if we need to show scroll buttons
*/
bool needShowScroll();
/**
* Returns true if chiclets can be scrolled left.
*/
bool canScrollLeft();
/**
* Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
*/
* Removes gaps between first chiclet and scroll area left side,
* last chiclet and scroll area right side.
* Verifies that chiclets can be scrolled left, then calls scroll()
* Verifies that chiclets can be scrolled right, then calls scroll()
/**
* Callback for right scroll button clicked
*/
/**
* Callback for right scroll button held down event
*/
Alexei Arabadji
committed
void onLeftScrollHeldDown();
Alexei Arabadji
committed
* Callback for left scroll button held down event
*/
void onRightScrollHeldDown();
* Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft()
* Notifies subscribers about click on chiclet.
* Do not place any code here, instead subscribe on event (see setChicletClickedCallback).
* Callback for chiclet size changed event, rearranges chiclets.
void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
Seth ProductEngine
committed
void onMessageCountChanged(const LLSD& data);
void objectChicletCallback(const LLSD& data);
typedef std::vector<LLChiclet*> chiclet_list_t;
void removeChiclet(chiclet_list_t::iterator it);
S32 getChicletPadding() { return mChicletPadding; }
S32 getScrollingOffset() { return mScrollingOffset; }
Steven Bennetts
committed
bool isAnyIMFloaterDoked();
protected:
chiclet_list_t mChicletList;
LLButton* mLeftScrollButton;
LLButton* mRightScrollButton;
LLPanel* mScrollArea;
Dmitry Zaporozhan
committed
S32 mScrollButtonHPad;
S32 mScrollRatio;
Alexei Arabadji
committed
static const S32 s_scroll_ratio;
T* LLChicletPanel::createChiclet(const LLUUID& session_id, S32 index)
{
typename T::Params params;
T* chiclet = LLUICtrlFactory::create<T>(params);
if(!chiclet)
{
LL_WARNS() << "Could not create chiclet" << LL_ENDL;
return NULL;
}
if(!addChiclet(chiclet, index))
{
delete chiclet;
LL_WARNS() << "Could not add chiclet to chiclet panel" << LL_ENDL;
Steven Bennetts
committed
if (!isAnyIMFloaterDoked())
{
scrollToChiclet(chiclet);
}
chiclet->setSessionId(session_id);
return chiclet;
}
template<class T>
T* LLChicletPanel::createChiclet(const LLUUID& session_id)
{
return createChiclet<T>(session_id, mChicletList.size());
}
template<class T>
T* LLChicletPanel::findChiclet(const LLUUID& im_session_id)
{
if(im_session_id.isNull())
{
return NULL;
}
chiclet_list_t::const_iterator it = mChicletList.begin();
for( ; mChicletList.end() != it; ++it)
{
LLChiclet* chiclet = *it;
if(chiclet->getSessionId() == im_session_id)
{
T* result = dynamic_cast<T*>(chiclet);
LL_WARNS() << "Found chiclet but of wrong type " << LL_ENDL;
}
return result;
}
}
return NULL;
}
template<class T> T* LLChicletPanel::getChiclet(S32 index)
{
if(index < 0 || index >= getChicletCount())
{
return NULL;
}
LLChiclet* chiclet = mChicletList[index];
T*result = dynamic_cast<T*>(chiclet);
if(!result && chiclet)
{
LL_WARNS() << "Found chiclet but of wrong type " << LL_ENDL;
#endif // LL_LLCHICLET_H