PageRenderTime 60ms CodeModel.GetById 15ms app.highlight 37ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/newview/llchiclet.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 1268 lines | 528 code | 274 blank | 466 comment | 18 complexity | 8e2a50594940cbe5df0928b3bd85046d MD5 | raw file
   1/** 
   2 * @file llchiclet.h
   3 * @brief LLChiclet class header file
   4 *
   5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#ifndef LL_LLCHICLET_H
  28#define LL_LLCHICLET_H
  29
  30#include "llavatariconctrl.h"
  31#include "llbutton.h"
  32#include "llpanel.h"
  33#include "lltextbox.h"
  34#include "lloutputmonitorctrl.h"
  35#include "llgroupmgr.h"
  36#include "llimview.h"
  37
  38class LLMenuGL;
  39class LLIMFloater;
  40
  41/**
  42 * Class for displaying amount of messages/notifications(unread).
  43 */
  44class LLChicletNotificationCounterCtrl : public LLTextBox
  45{
  46public:
  47
  48	struct Params :	public LLInitParam::Block<Params, LLTextBox::Params>
  49	{
  50		/**
  51		* Contains maximum displayed count of unread messages. Default value is 9.
  52		*
  53		* If count is less than "max_unread_count" will be displayed as is.
  54		* Otherwise 9+ will be shown (for default value).
  55		*/
  56		Optional<S32> max_displayed_count;
  57
  58		Params();
  59	};
  60
  61	/**
  62	 * Sets number of notifications
  63	 */
  64	virtual void setCounter(S32 counter);
  65
  66	/**
  67	 * Returns number of notifications
  68	 */
  69	virtual S32 getCounter() const { return mCounter; }
  70
  71	/**
  72	 * Returns width, required to display amount of notifications in text form.
  73	 * Width is the only valid value.
  74	 */
  75	/*virtual*/ LLRect getRequiredRect();
  76
  77	/**
  78	 * Sets number of notifications using LLSD
  79	 */
  80	/*virtual*/ void setValue(const LLSD& value);
  81
  82	/**
  83	 * Returns number of notifications wrapped in LLSD
  84	 */
  85	/*virtual*/ LLSD getValue() const;
  86
  87protected:
  88
  89	LLChicletNotificationCounterCtrl(const Params& p);
  90	friend class LLUICtrlFactory;
  91
  92private:
  93
  94	S32 mCounter;
  95	S32 mInitialWidth;
  96	S32 mMaxDisplayedCount;
  97};
  98
  99/**
 100 * Class for displaying avatar's icon in P2P chiclet.
 101 */
 102class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
 103{
 104public:
 105
 106	struct Params :	public LLInitParam::Block<Params, LLAvatarIconCtrl::Params>
 107	{
 108		Params()
 109		{
 110			changeDefault(draw_tooltip, FALSE);
 111			changeDefault(mouse_opaque, FALSE);
 112			changeDefault(default_icon_name, "Generic_Person");
 113		};
 114	};
 115
 116protected:
 117
 118	LLChicletAvatarIconCtrl(const Params& p);
 119	friend class LLUICtrlFactory;
 120};
 121
 122/**
 123 * Class for displaying group's icon in Group chiclet.
 124 */
 125class LLChicletGroupIconCtrl : public LLIconCtrl
 126{
 127public:
 128
 129	struct Params :	public LLInitParam::Block<Params, LLIconCtrl::Params>
 130	{
 131		Optional<std::string> default_icon;
 132
 133		Params()
 134		:	default_icon("default_icon", "Generic_Group")
 135		{}
 136	};
 137
 138	/**
 139	 * Sets icon, if value is LLUUID::null - default icon will be set.
 140	 */
 141	virtual void setValue(const LLSD& value );
 142
 143protected:
 144
 145	LLChicletGroupIconCtrl(const Params& p);
 146	friend class LLUICtrlFactory;
 147
 148	std::string mDefaultIcon;
 149};
 150
 151/**
 152 * Class for displaying icon in inventory offer chiclet.
 153 */
 154class LLChicletInvOfferIconCtrl : public LLChicletAvatarIconCtrl
 155{
 156public:
 157
 158	struct Params :
 159		public LLInitParam::Block<Params, LLChicletAvatarIconCtrl::Params>
 160	{
 161		Optional<std::string> default_icon;
 162
 163		Params()
 164		:	default_icon("default_icon", "Generic_Object_Small")
 165		{
 166			changeDefault(avatar_id, LLUUID::null);
 167		};
 168	};
 169
 170	/**
 171	 * Sets icon, if value is LLUUID::null - default icon will be set.
 172	 */
 173	virtual void setValue(const LLSD& value );
 174
 175protected:
 176
 177	LLChicletInvOfferIconCtrl(const Params& p);
 178	friend class LLUICtrlFactory;
 179
 180private:
 181	std::string mDefaultIcon;
 182};
 183
 184/**
 185 * Class for displaying of speaker's voice indicator 
 186 */
 187class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl
 188{
 189public:
 190
 191	struct Params : public LLInitParam::Block<Params, LLOutputMonitorCtrl::Params>
 192	{
 193		Params(){};
 194	};
 195protected:
 196
 197	LLChicletSpeakerCtrl(const Params&p);
 198	friend class LLUICtrlFactory;
 199};
 200
 201/**
 202 * Base class for all chiclets.
 203 */
 204class LLChiclet : public LLUICtrl
 205{
 206public:
 207
 208	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 209	{
 210		Optional<bool> show_counter,
 211					   enable_counter;
 212
 213		Params();
 214	};
 215
 216	/*virtual*/ ~LLChiclet();
 217
 218	/**
 219	 * Associates chat session id with chiclet.
 220	 */
 221	virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; }
 222
 223	/**
 224	 * Returns associated chat session.
 225	 */
 226	virtual const LLUUID& getSessionId() const { return mSessionId; }
 227
 228	/**
 229	 * Sets number of unread notifications.
 230	 */
 231	virtual void setCounter(S32 counter) = 0;
 232
 233	/**
 234	 * Returns number of unread notifications.
 235	 */
 236	virtual S32 getCounter() = 0;
 237
 238	/**
 239	 * Sets show counter state.
 240	 */
 241	virtual void setShowCounter(bool show) { mShowCounter = show; }
 242
 243	/**
 244	 * Returns show counter state.
 245	 */
 246	virtual bool getShowCounter() {return mShowCounter;};
 247
 248	/**
 249	 * Connects chiclet clicked event with callback.
 250	 */
 251	/*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
 252		const commit_callback_t& cb);
 253
 254	typedef boost::function<void (LLChiclet* ctrl, const LLSD& param)> 
 255		chiclet_size_changed_callback_t;
 256
 257	/**
 258	 * Connects chiclets size changed event with callback.
 259	 */
 260	virtual boost::signals2::connection setChicletSizeChangedCallback(
 261		const chiclet_size_changed_callback_t& cb);
 262
 263	/**
 264	 * Sets IM Session id using LLSD
 265	 */
 266	/*virtual*/ LLSD getValue() const;
 267
 268	/**
 269	 * Returns IM Session id using LLSD
 270	 */
 271	/*virtual*/ void setValue(const LLSD& value);
 272
 273protected:
 274
 275	friend class LLUICtrlFactory;
 276	LLChiclet(const Params& p);
 277
 278	/**
 279	 * Notifies subscribers about click on chiclet.
 280	 */
 281	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
 282
 283	/**
 284	 * Notifies subscribers about chiclet size changed event.
 285	 */
 286	virtual void onChicletSizeChanged();
 287
 288private:
 289
 290	LLUUID mSessionId;
 291
 292	bool mShowCounter;
 293
 294	typedef boost::signals2::signal<void (LLChiclet* ctrl, const LLSD& param)> 
 295		chiclet_size_changed_signal_t;
 296
 297	chiclet_size_changed_signal_t mChicletSizeChangedSignal;
 298};
 299
 300
 301/**
 302 * Base class for Instant Message chiclets.
 303 * IMChiclet displays icon, number of unread messages(optional)
 304 * and voice chat status(optional).
 305 */
 306class LLIMChiclet : public LLChiclet
 307{
 308public:
 309	enum EType {
 310		TYPE_UNKNOWN,
 311		TYPE_IM,
 312		TYPE_GROUP,
 313		TYPE_AD_HOC
 314	};
 315	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
 316	{};
 317
 318	
 319	virtual ~LLIMChiclet() {};
 320
 321	/**
 322	 * It is used for default setting up of chicklet:click handler, etc.  
 323	 */
 324	BOOL postBuild();
 325	/**
 326	 * Sets IM session name. This name will be displayed in chiclet tooltip.
 327	 */
 328	virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
 329
 330	/**
 331	 * Sets id of person/group user is chatting with.
 332	 * Session id should be set before calling this
 333	 */
 334	virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
 335
 336	/**
 337	 * Gets id of person/group user is chatting with.
 338	 */
 339	virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }
 340
 341	/**
 342	 * Init Speaker Control with speaker's ID
 343	 */
 344	virtual void initSpeakerControl();
 345
 346	/**
 347	 * set status (Shows/Hide) for voice control.
 348	 */
 349	virtual void setShowSpeaker(bool show);
 350
 351	/**
 352	 * Returns voice chat status control visibility.
 353	 */
 354	virtual bool getShowSpeaker() {return mShowSpeaker;};
 355
 356	/**
 357	 * Shows/Hides for voice control for a chiclet.
 358	 */
 359	virtual void toggleSpeakerControl();
 360
 361	/**
 362	* Sets number of unread messages. Will update chiclet's width if number text 
 363	* exceeds size of counter and notify it's parent about size change.
 364	*/
 365	virtual void setCounter(S32);
 366
 367	/**
 368	* Enables/disables the counter control for a chiclet.
 369	*/
 370	virtual void enableCounterControl(bool enable);
 371
 372	/**
 373	* Sets show counter state.
 374	*/
 375	virtual void setShowCounter(bool show);
 376
 377	/**
 378	* Shows/Hides for counter control for a chiclet.
 379	*/
 380	virtual void toggleCounterControl();
 381
 382	/**
 383	* Sets required width for a chiclet according to visible controls.
 384	*/
 385	virtual void setRequiredWidth();
 386
 387	/**
 388	 * Shows/hides overlay icon concerning new unread messages.
 389	 */
 390	virtual void setShowNewMessagesIcon(bool show);
 391
 392	/**
 393	 * Returns visibility of overlay icon concerning new unread messages.
 394	 */
 395	virtual bool getShowNewMessagesIcon();
 396
 397	virtual void draw();
 398
 399	/**
 400	 * Determine whether given ID refers to a group or an IM chat session.
 401	 * 
 402	 * This is used when we need to chose what IM chiclet (P2P/group)
 403	 * class to instantiate.
 404	 * 
 405	 * @param session_id session ID.
 406	 * @return TYPE_GROUP in case of group chat session,
 407	 *         TYPE_IM in case of P2P session,
 408	 *         TYPE_UNKNOWN otherwise.
 409	 */
 410	static EType getIMSessionType(const LLUUID& session_id);
 411
 412	/**
 413	 * The action taken on mouse down event.
 414	 * 
 415	 * Made public so that it can be triggered from outside
 416	 * (more specifically, from the Active IM window).
 417	 */
 418	virtual void onMouseDown();
 419
 420	virtual void setToggleState(bool toggle);
 421
 422	/**
 423	 * Displays popup menu.
 424	 */
 425	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
 426
 427protected:
 428
 429	LLIMChiclet(const LLIMChiclet::Params& p);
 430
 431protected:
 432
 433	/**
 434	 * Creates chiclet popup menu.
 435	 */
 436	virtual void createPopupMenu() = 0;
 437
 438	/** 
 439	 * Enables/disables menus.
 440	 */
 441	virtual void updateMenuItems() {};
 442
 443	bool canCreateMenu();
 444
 445	LLMenuGL* mPopupMenu;
 446
 447	bool mShowSpeaker;
 448	bool mCounterEnabled;
 449	/* initial width of chiclet, should not include counter or speaker width */
 450	S32 mDefaultWidth;
 451
 452	LLIconCtrl* mNewMessagesIcon;
 453	LLChicletNotificationCounterCtrl* mCounterCtrl;
 454	LLChicletSpeakerCtrl* mSpeakerCtrl;
 455	LLButton* mChicletButton;
 456
 457	/** the id of another participant, either an avatar id or a group id*/
 458	LLUUID mOtherParticipantId;
 459
 460	template<typename Container>
 461	struct CollectChicletCombiner {
 462		typedef Container result_type;
 463
 464		template<typename InputIterator>
 465		Container operator()(InputIterator first, InputIterator last) const {
 466			Container c = Container();
 467			for (InputIterator iter = first; iter != last; iter++) {
 468				if (*iter != NULL) {
 469					c.push_back(*iter);
 470				}
 471			}
 472			return c;
 473		}
 474	};
 475
 476public:
 477	static boost::signals2::signal<LLChiclet* (const LLUUID&),
 478			CollectChicletCombiner<std::list<LLChiclet*> > >
 479			sFindChicletsSignal;
 480};
 481
 482/**
 483 * Implements P2P chiclet.
 484 */
 485class LLIMP2PChiclet : public LLIMChiclet
 486{
 487public:
 488	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
 489	{
 490		Optional<LLButton::Params> chiclet_button;
 491
 492		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
 493
 494		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
 495
 496		Optional<LLChicletSpeakerCtrl::Params> speaker;
 497
 498		Optional<LLIconCtrl::Params> new_message_icon;
 499
 500		Optional<bool>	show_speaker;
 501
 502		Params();
 503	};
 504
 505	/* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id);
 506
 507	/**
 508	 * Init Speaker Control with speaker's ID
 509	 */
 510	/*virtual*/ void initSpeakerControl();
 511
 512	/**
 513	 * Returns number of unread messages.
 514	 */
 515	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
 516
 517protected:
 518	LLIMP2PChiclet(const Params& p);
 519	friend class LLUICtrlFactory;
 520
 521	/**
 522	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
 523	 * based on other participant's id.
 524	 */
 525	virtual void createPopupMenu();
 526
 527	/**
 528	 * Processes clicks on chiclet popup menu.
 529	 */
 530	virtual void onMenuItemClicked(const LLSD& user_data);
 531
 532	/** 
 533	 * Enables/disables menus based on relationship with other participant.
 534	 * Enables/disables "show session" menu item depending on visible IM floater existence.
 535	 */
 536	virtual void updateMenuItems();
 537
 538private:
 539
 540	LLChicletAvatarIconCtrl* mChicletIconCtrl;
 541};
 542
 543/**
 544 * Implements AD-HOC chiclet.
 545 */
 546class LLAdHocChiclet : public LLIMChiclet
 547{
 548public:
 549	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
 550	{
 551		Optional<LLButton::Params> chiclet_button;
 552
 553		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
 554
 555		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
 556
 557		Optional<LLChicletSpeakerCtrl::Params> speaker;
 558
 559		Optional<LLIconCtrl::Params> new_message_icon;
 560
 561		Optional<bool>	show_speaker;
 562
 563		Optional<LLColor4>	avatar_icon_color;
 564
 565		Params();
 566	};
 567
 568	/**
 569	 * Sets session id.
 570	 * Session ID for group chat is actually Group ID.
 571	 */
 572	/*virtual*/ void setSessionId(const LLUUID& session_id);
 573
 574	/**
 575	 * Keep Speaker Control with actual speaker's ID
 576	 */
 577	/*virtual*/ void draw();
 578
 579	/**
 580	 * Init Speaker Control with speaker's ID
 581	 */
 582	/*virtual*/ void initSpeakerControl();
 583
 584	/**
 585	 * Returns number of unread messages.
 586	 */
 587	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
 588
 589protected:
 590	LLAdHocChiclet(const Params& p);
 591	friend class LLUICtrlFactory;
 592
 593	/**
 594	 * Creates chiclet popup menu. Will create AdHoc Chat menu 
 595	 * based on other participant's id.
 596	 */
 597	virtual void createPopupMenu();
 598
 599	/**
 600	 * Processes clicks on chiclet popup menu.
 601	 */
 602	virtual void onMenuItemClicked(const LLSD& user_data);
 603
 604	/**
 605	 * Finds a current speaker and resets the SpeakerControl with speaker's ID
 606	 */
 607	/*virtual*/ void switchToCurrentSpeaker();
 608
 609private:
 610
 611	LLChicletAvatarIconCtrl* mChicletIconCtrl;
 612};
 613
 614/**
 615 * Chiclet for script floaters.
 616 */
 617class LLScriptChiclet : public LLIMChiclet
 618{
 619public:
 620
 621	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
 622	{
 623		Optional<LLButton::Params> chiclet_button;
 624
 625		Optional<LLIconCtrl::Params> icon;
 626
 627		Optional<LLIconCtrl::Params> new_message_icon;
 628
 629		Params();
 630	};
 631
 632	/*virtual*/ void setSessionId(const LLUUID& session_id);
 633
 634	/*virtual*/ void setCounter(S32 counter);
 635
 636	/*virtual*/ S32 getCounter() { return 0; }
 637
 638	/**
 639	 * Toggle script floater
 640	 */
 641	/*virtual*/ void onMouseDown();
 642
 643protected:
 644
 645	LLScriptChiclet(const Params&);
 646	friend class LLUICtrlFactory;
 647
 648	/**
 649	 * Creates chiclet popup menu.
 650	 */
 651	virtual void createPopupMenu();
 652
 653	/**
 654	 * Processes clicks on chiclet popup menu.
 655	 */
 656	virtual void onMenuItemClicked(const LLSD& user_data);
 657
 658private:
 659
 660	LLIconCtrl* mChicletIconCtrl;
 661};
 662
 663/**
 664 * Chiclet for inventory offer script floaters.
 665 */
 666class LLInvOfferChiclet: public LLIMChiclet
 667{
 668public:
 669
 670	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
 671	{
 672		Optional<LLButton::Params> chiclet_button;
 673
 674		Optional<LLChicletInvOfferIconCtrl::Params> icon;
 675
 676		Optional<LLIconCtrl::Params> new_message_icon;
 677
 678		Params();
 679	};
 680
 681	/*virtual*/ void setSessionId(const LLUUID& session_id);
 682
 683	/*virtual*/ void setCounter(S32 counter);
 684
 685	/*virtual*/ S32 getCounter() { return 0; }
 686
 687	/**
 688	 * Toggle script floater
 689	 */
 690	/*virtual*/ void onMouseDown();
 691
 692protected:
 693	LLInvOfferChiclet(const Params&);
 694	friend class LLUICtrlFactory;
 695
 696	/**
 697	 * Creates chiclet popup menu.
 698	 */
 699	virtual void createPopupMenu();
 700
 701	/**
 702	 * Processes clicks on chiclet popup menu.
 703	 */
 704	virtual void onMenuItemClicked(const LLSD& user_data);
 705
 706private:
 707	LLChicletInvOfferIconCtrl* mChicletIconCtrl;
 708};
 709
 710/**
 711 * Implements Group chat chiclet.
 712 */
 713class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver
 714{
 715public:
 716
 717	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
 718	{
 719		Optional<LLButton::Params> chiclet_button;
 720
 721		Optional<LLChicletGroupIconCtrl::Params> group_icon;
 722
 723		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
 724
 725		Optional<LLChicletSpeakerCtrl::Params> speaker;
 726
 727		Optional<LLIconCtrl::Params> new_message_icon;
 728
 729		Optional<bool>	show_speaker;
 730
 731		Params();
 732	};
 733
 734	/**
 735	 * Sets session id.
 736	 * Session ID for group chat is actually Group ID.
 737	 */
 738	/*virtual*/ void setSessionId(const LLUUID& session_id);
 739
 740	/**
 741	 * Keep Speaker Control with actual speaker's ID
 742	 */
 743	/*virtual*/ void draw();
 744
 745	/**
 746	 * Callback for LLGroupMgrObserver, we get this when group data is available or changed.
 747	 * Sets group icon.
 748	 */
 749	/*virtual*/ void changed(LLGroupChange gc);
 750
 751	/**
 752	 * Init Speaker Control with speaker's ID
 753	 */
 754	/*virtual*/ void initSpeakerControl();
 755
 756	/**
 757	 * Returns number of unread messages.
 758	 */
 759	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
 760
 761	~LLIMGroupChiclet();
 762
 763protected:
 764	LLIMGroupChiclet(const Params& p);
 765	friend class LLUICtrlFactory;
 766
 767	/**
 768	 * Finds a current speaker and resets the SpeakerControl with speaker's ID
 769	 */
 770	/*virtual*/ void switchToCurrentSpeaker();
 771
 772	/**
 773	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
 774	 * based on other participant's id.
 775	 */
 776	virtual void createPopupMenu();
 777
 778	/**
 779	 * Processes clicks on chiclet popup menu.
 780	 */
 781	virtual void onMenuItemClicked(const LLSD& user_data);
 782
 783	/**
 784	 * Enables/disables "show session" menu item depending on visible IM floater existence.
 785	 */
 786	virtual void updateMenuItems();
 787
 788private:
 789
 790	LLChicletGroupIconCtrl* mChicletIconCtrl;
 791};
 792
 793/**
 794 * Implements notification chiclet. Used to display total amount of unread messages 
 795 * across all IM sessions, total amount of system notifications. See EXT-3147 for details
 796 */
 797class LLSysWellChiclet : public LLChiclet
 798{
 799public:
 800
 801	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
 802	{
 803		Optional<LLButton::Params> button;
 804
 805		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
 806
 807		/**
 808		 * Contains maximum displayed count of unread messages. Default value is 9.
 809		 *
 810		 * If count is less than "max_unread_count" will be displayed as is.
 811		 * Otherwise 9+ will be shown (for default value).
 812		 */
 813		Optional<S32> max_displayed_count;
 814
 815		Params();
 816	};
 817
 818	/*virtual*/ void setCounter(S32 counter);
 819
 820	// *TODO: mantipov: seems getCounter is not necessary for LLNotificationChiclet
 821	// but inherited interface requires it to implement. 
 822	// Probably it can be safe removed.
 823	/*virtual*/S32 getCounter() { return mCounter; }
 824
 825	boost::signals2::connection setClickCallback(const commit_callback_t& cb);
 826
 827	/*virtual*/ ~LLSysWellChiclet();
 828
 829	void setToggleState(BOOL toggled);
 830
 831	void setNewMessagesState(bool new_messages);
 832	//this method should change a widget according to state of the SysWellWindow 
 833	virtual void updateWidget(bool is_window_empty);
 834
 835protected:
 836
 837	LLSysWellChiclet(const Params& p);
 838	friend class LLUICtrlFactory;
 839
 840	/**
 841	 * Change Well 'Lit' state from 'Lit' to 'Unlit' and vice-versa.
 842	 *
 843	 * There is an assumption that it will be called 2*N times to do not change its start state.
 844	 * @see FlashToLitTimer
 845	 */
 846	void changeLitState();
 847
 848	/**
 849	 * Displays menu.
 850	 */
 851	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
 852
 853	virtual void createMenu() = 0;
 854
 855protected:
 856	class FlashToLitTimer;
 857	LLButton* mButton;
 858	S32 mCounter;
 859	S32 mMaxDisplayedCount;
 860	bool mIsNewMessagesState;
 861
 862	FlashToLitTimer* mFlashToLitTimer;
 863	LLContextMenu* mContextMenu;
 864};
 865
 866/**
 867 * Class represented a chiclet for IM Well Icon.
 868 *
 869 * It displays a count of unread messages from other participants in all IM sessions.
 870 */
 871class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
 872{
 873	friend class LLUICtrlFactory;
 874public:
 875	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
 876	virtual void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
 877	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
 878
 879	~LLIMWellChiclet();
 880protected:
 881	LLIMWellChiclet(const Params& p);
 882
 883	/**
 884	 * Processes clicks on chiclet popup menu.
 885	 */
 886	virtual void onMenuItemClicked(const LLSD& user_data);
 887
 888	/**
 889	 * Enables chiclet menu items.
 890	 */
 891	bool enableMenuItem(const LLSD& user_data);
 892
 893	/**
 894	 * Creates menu.
 895	 */
 896	/*virtual*/ void createMenu();
 897
 898	/**
 899	 * Handles changes in a session (message was added, messages were read, etc.)
 900	 *
 901	 * It get total count of unread messages from a LLIMMgr in all opened sessions and display it.
 902	 *
 903	 * @param[in] session_data contains session related data, is not used now
 904	 *		["session_id"] - id of an appropriate session
 905	 *		["participant_unread"] - count of unread messages from "real" participants.
 906	 *
 907	 * @see LLIMMgr::getNumberOfUnreadParticipantMessages()
 908	 */
 909	void messageCountChanged(const LLSD& session_data);
 910};
 911
 912class LLNotificationChiclet : public LLSysWellChiclet
 913{
 914	friend class LLUICtrlFactory;
 915public:
 916	struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
 917
 918protected:
 919	LLNotificationChiclet(const Params& p);
 920
 921	/**
 922	 * Processes clicks on chiclet menu.
 923	 */
 924	void onMenuItemClicked(const LLSD& user_data);
 925
 926	/**
 927	 * Enables chiclet menu items.
 928	 */
 929	bool enableMenuItem(const LLSD& user_data);
 930
 931	/**
 932	 * Creates menu.
 933	 */
 934	/*virtual*/ void createMenu();
 935
 936	// connect counter updaters to the corresponding signals
 937	void connectCounterUpdatersToSignal(const std::string& notification_type);
 938
 939	// methods for updating a number of unread System notifications
 940	void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); }
 941	void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); }
 942	/*virtual*/ void setCounter(S32 counter);
 943	S32 mUreadSystemNotifications;
 944};
 945
 946/**
 947 * Storage class for all IM chiclets. Provides mechanism to display, 
 948 * scroll, create, remove chiclets.
 949 */
 950class LLChicletPanel : public LLPanel
 951{
 952public:
 953
 954	struct Params :	public LLInitParam::Block<Params, LLPanel::Params>
 955	{
 956		Optional<S32> chiclet_padding,
 957					  scrolling_offset,
 958					  scroll_button_hpad,
 959					  scroll_ratio;
 960
 961		Optional<S32> min_width;
 962
 963		Params();
 964	};
 965
 966	virtual ~LLChicletPanel();
 967
 968	/**
 969	 * Creates chiclet and adds it to chiclet list at specified index.
 970	 */
 971	template<class T> T* createChiclet(const LLUUID& session_id, S32 index);
 972
 973	/**
 974	 * Creates chiclet and adds it to chiclet list at right.
 975	 */
 976	template<class T> T* createChiclet(const LLUUID& session_id);
 977
 978	/**
 979	 * Returns pointer to chiclet of specified type at specified index.
 980	 */
 981	template<class T> T* getChiclet(S32 index);
 982
 983	/**
 984	 * Returns pointer to LLChiclet at specified index.
 985	 */
 986	LLChiclet* getChiclet(S32 index) { return getChiclet<LLChiclet>(index); }
 987
 988	/**
 989	 * Searches a chiclet using IM session id.
 990	 */
 991	template<class T> T* findChiclet(const LLUUID& im_session_id);
 992
 993	/**
 994	 * Returns number of hosted chiclets.
 995	 */
 996	S32 getChicletCount() {return mChicletList.size();};
 997
 998	/**
 999	 * Returns index of chiclet in list.
1000	 */
1001	S32 getChicletIndex(const LLChiclet* chiclet);
1002
1003	/**
1004	 * Removes chiclet by index.
1005	 */
1006	void removeChiclet(S32 index);
1007
1008	/**
1009	 * Removes chiclet by pointer.
1010	 */
1011	void removeChiclet(LLChiclet* chiclet);
1012
1013	/**
1014	 * Removes chiclet by IM session id.
1015	 */
1016	void removeChiclet(const LLUUID& im_session_id);
1017
1018	/**
1019	 * Removes all chiclets.
1020	 */
1021	void removeAll();
1022
1023	/**
1024	 * Scrolls the panel to the specified chiclet
1025	 */
1026	void scrollToChiclet(const LLChiclet* chiclet);
1027
1028	boost::signals2::connection setChicletClickedCallback(
1029		const commit_callback_t& cb);
1030
1031	/*virtual*/ BOOL postBuild();
1032
1033	/**
1034	 * Handler for the Voice Client's signal. Finds a corresponding chiclet and toggles its SpeakerControl
1035	 */
1036	void onCurrentVoiceChannelChanged(const LLUUID& session_id);
1037
1038	/**
1039	 * Reshapes controls and rearranges chiclets if needed.
1040	 */
1041	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
1042
1043	/*virtual*/ void draw();
1044
1045	S32 getMinWidth() const { return mMinWidth; }
1046
1047	S32 getTotalUnreadIMCount();
1048
1049	S32	notifyParent(const LLSD& info);
1050
1051	/**
1052	 * Toggle chiclet by session id ON and toggle OFF all other chiclets.
1053	 */
1054	void setChicletToggleState(const LLUUID& session_id, bool toggle);
1055
1056protected:
1057	LLChicletPanel(const Params&p);
1058	friend class LLUICtrlFactory;
1059
1060	/**
1061	 * Adds chiclet to list and rearranges all chiclets. 
1062	 * They should be right aligned, most recent right. See EXT-1293
1063	 *
1064	 * It calculates position of the first chiclet in the list. Other chiclets are placed in arrange().
1065	 *
1066	 * @see arrange()
1067	 */
1068	bool addChiclet(LLChiclet*, S32 index);
1069
1070	/**
1071	 * Arranges chiclets to have them in correct positions.
1072	 *
1073	 * Method bases on assumption that first chiclet has correct rect and starts from the its position.
1074	 *
1075	 * @see addChiclet()
1076	 */
1077	void arrange();
1078
1079	/**
1080	 * Returns true if chiclets can be scrolled right.
1081	 */
1082	bool canScrollRight();
1083
1084	/**
1085	 * Returns true if we need to show scroll buttons
1086	 */
1087	bool needShowScroll();
1088
1089	/**
1090	 * Returns true if chiclets can be scrolled left.
1091	 */
1092	bool canScrollLeft();
1093
1094	/**
1095	 * Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
1096	 */
1097	void showScrollButtonsIfNeeded();
1098
1099	/**
1100	 * Shifts chiclets left or right.
1101	 */
1102	void shiftChiclets(S32 offset, S32 start_index = 0);
1103
1104	/**
1105	 * Removes gaps between first chiclet and scroll area left side,
1106	 * last chiclet and scroll area right side.
1107	 */
1108	void trimChiclets();
1109
1110	/**
1111	 * Scrolls chiclets to right or left.
1112	 */
1113	void scroll(S32 offset);
1114
1115	/**
1116	 * Verifies that chiclets can be scrolled left, then calls scroll()
1117	 */
1118	void scrollLeft();
1119
1120	/**
1121	 * Verifies that chiclets can be scrolled right, then calls scroll()
1122	 */
1123	void scrollRight();
1124
1125	/**
1126	 * Callback for left scroll button clicked
1127	 */
1128	void onLeftScrollClick();
1129
1130	/**
1131	 * Callback for right scroll button clicked
1132	 */
1133	void onRightScrollClick();
1134
1135	/**
1136	 * Callback for right scroll button held down event
1137	 */
1138	void onLeftScrollHeldDown();
1139
1140	/**
1141	 * Callback for left scroll button held down event
1142	 */
1143	void onRightScrollHeldDown();
1144
1145	/**
1146	 * Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft()
1147	 */
1148	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
1149
1150	/**
1151	 * Notifies subscribers about click on chiclet.
1152	 * Do not place any code here, instead subscribe on event (see setChicletClickedCallback).
1153	 */
1154	void onChicletClick(LLUICtrl*ctrl,const LLSD&param);
1155
1156	/**
1157	 * Callback for chiclet size changed event, rearranges chiclets.
1158	 */
1159	void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
1160
1161	typedef std::vector<LLChiclet*> chiclet_list_t;
1162
1163	/**
1164	 * Removes chiclet from scroll area and chiclet list.
1165	 */
1166	void removeChiclet(chiclet_list_t::iterator it);
1167
1168	S32 getChicletPadding() { return mChicletPadding; }
1169
1170	S32 getScrollingOffset() { return mScrollingOffset; }
1171
1172	bool isAnyIMFloaterDoked();
1173
1174protected:
1175
1176	chiclet_list_t mChicletList;
1177	LLButton* mLeftScrollButton;
1178	LLButton* mRightScrollButton;
1179	LLPanel* mScrollArea;
1180
1181	S32 mChicletPadding;
1182	S32 mScrollingOffset;
1183	S32 mScrollButtonHPad;
1184	S32 mScrollRatio;
1185	S32 mMinWidth;
1186	bool mShowControls;
1187	static const S32 s_scroll_ratio;
1188};
1189
1190template<class T> 
1191T* LLChicletPanel::createChiclet(const LLUUID& session_id, S32 index)
1192{
1193	typename T::Params params;
1194	T* chiclet = LLUICtrlFactory::create<T>(params);
1195	if(!chiclet)
1196	{
1197		llwarns << "Could not create chiclet" << llendl;
1198		return NULL;
1199	}
1200	if(!addChiclet(chiclet, index))
1201	{
1202		delete chiclet;
1203		llwarns << "Could not add chiclet to chiclet panel" << llendl;
1204		return NULL;
1205	}
1206
1207	if (!isAnyIMFloaterDoked())
1208	{
1209		scrollToChiclet(chiclet);
1210	}
1211
1212	chiclet->setSessionId(session_id);
1213
1214	return chiclet;
1215}
1216
1217template<class T>
1218T* LLChicletPanel::createChiclet(const LLUUID& session_id)
1219{
1220	return createChiclet<T>(session_id, mChicletList.size());
1221}
1222
1223template<class T>
1224T* LLChicletPanel::findChiclet(const LLUUID& im_session_id)
1225{
1226	if(im_session_id.isNull())
1227	{
1228		return NULL;
1229	}
1230
1231	chiclet_list_t::const_iterator it = mChicletList.begin();
1232	for( ; mChicletList.end() != it; ++it)
1233	{
1234		LLChiclet* chiclet = *it;
1235
1236		llassert(chiclet);
1237		if (!chiclet) continue;
1238		if(chiclet->getSessionId() == im_session_id)
1239		{
1240			T* result = dynamic_cast<T*>(chiclet);
1241			if(!result)
1242			{
1243				llwarns << "Found chiclet but of wrong type " << llendl;
1244				continue;
1245			}
1246			return result;
1247		}
1248	}
1249	return NULL;
1250}
1251
1252template<class T> T* LLChicletPanel::getChiclet(S32 index)
1253{
1254	if(index < 0 || index >= getChicletCount())
1255	{
1256		return NULL;
1257	}
1258
1259	LLChiclet* chiclet = mChicletList[index];
1260	T*result = dynamic_cast<T*>(chiclet);
1261	if(!result && chiclet)
1262	{
1263		llwarns << "Found chiclet but of wrong type " << llendl;
1264	}
1265	return result;
1266}
1267
1268#endif // LL_LLCHICLET_H