From 8f7ec64899c54dcee6caa0307510cc4003ba7bdd Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 27 Jul 2009 17:56:26 +0000 Subject: Merged skinning-17 into viewer-2 for bug fixes. Commented out new IM window for now, not complete. Merging revisions 127913-128319 of svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-17 into D:\viewer-2.0.0-3, respecting ancestry --- indra/newview/llimpanel.cpp | 235 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 216 insertions(+), 19 deletions(-) (limited to 'indra/newview/llimpanel.cpp') diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 5b4f711099..248a8dbc4c 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -45,8 +45,10 @@ #include "llagent.h" #include "llbutton.h" +#include "llbottomtray.h" #include "llcallingcard.h" #include "llchat.h" +#include "llchiclet.h" #include "llconsole.h" #include "llfloater.h" #include "llfloatercall.h" @@ -57,9 +59,12 @@ #include "llinventorymodel.h" #include "llfloaterinventory.h" #include "llfloaterchat.h" +#include "lliconctrl.h" +#include "llimview.h" // for LLIMModel to get other avatar id in chat #include "llkeyboard.h" #include "lllineeditor.h" #include "llnotify.h" +#include "llpanelimcontrolpanel.h" #include "llrecentpeople.h" #include "llresmgr.h" #include "lltrans.h" @@ -2040,7 +2045,7 @@ bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const } return false; } - + std::map LLIMFloater::sIMFloaterMap; @@ -2048,23 +2053,183 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id, const std::string title, EInstantMessage dialog) : mSessionID(session_id), - mIndex(0) + mLastMessageIndex(-1), + mDialog(dialog) { LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml"); sIMFloaterMap[mSessionID] = this; + LLPanelIMControlPanel* im_control_panel = getChild("panel_im_control_panel"); + + LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, session_id, (LLIMModel::LLIMSession*)NULL); + if(session) + { + mOtherParticipantUUID = session->mOtherParticipantID; + im_control_panel->setAvatarId(session->mOtherParticipantID); + } + + LLButton* slide_left = getChild("slide_left_btn"); + slide_left->setVisible(im_control_panel->getVisible()); + slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + + LLButton* slide_right = getChild("slide_right_btn"); + slide_right->setVisible(!im_control_panel->getVisible()); + slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this)); + setTitle(title); + setDocked(true); + + mInputEditor = getChild("chat_editor"); + + + mInputEditor->setMaxTextLength(1023); + // enable line history support for instant message bar + mInputEditor->setEnableLineHistory(TRUE); + + mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this ); + mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this ); + mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this ); + mInputEditor->setCommitOnFocusLost( FALSE ); + mInputEditor->setRevertOnEsc( FALSE ); + mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); + + childSetCommitCallback("chat_editor", onSendMsg, this); +} + +/* static */ +void LLIMFloater::newIMCallback(const LLSD& data){ + + if (data["num_unread"].asInteger() > 0) + { + LLUUID session_id = data["session_id"].asUUID(); + + LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL); + + if (floater == NULL) + { + llwarns << "new_im_callback for non-existent session_id " << session_id << llendl; + return; + } + + // update if visible, otherwise will be updated when opened + if (floater->getVisible()) + { + floater->updateMessages(); + } + } +} + +void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata ) +{ + LLIMFloater* self = (LLIMFloater*) userdata; + self->sendMsg(); } +void LLIMFloater::sendMsg() +{ + if (!gAgent.isGodlike() + && (mDialog == IM_NOTHING_SPECIAL) + && mOtherParticipantUUID.isNull()) + { + llinfos << "Cannot send IM to everyone unless you're a god." << llendl; + return; + } + + if (mInputEditor) + { + LLWString text = mInputEditor->getConvertedText(); + if(!text.empty()) + { + // Truncate and convert to UTF8 for transport + std::string utf8_text = wstring_to_utf8str(text); + utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); + + LLIMModel::sendMessage(utf8_text, + mSessionID, + mOtherParticipantUUID, + mDialog); + + mInputEditor->setText(LLStringUtil::null); + + updateMessages(); + } + } +} + + + LLIMFloater::~LLIMFloater() { sIMFloaterMap.erase(mSessionID); } +//virtual +BOOL LLIMFloater::postBuild() +{ + mHistoryEditor = getChild("im_text", true, false); + mChiclet = LLBottomTray::getInstance()->getChicletPanel()->findChiclet(mSessionID); + + if (!mChiclet) + { + llwarns << "No chiclet found for the IMFloter" << llendl; + } + setDocked(false); + return TRUE; +} + +const U32 UNDOCK_LEAP_HEIGHT = 12; +const U32 DOCK_ICON_HEIGHT = 6; -void LLIMFloater::show(const LLUUID& session_id, S32 center_x) +//virtual +void LLIMFloater::onFocusLost() { + // spec says close if docked to bottom tray and user has clicked away + // (hence we are no longer focused) + if (isDocked()) + { + // app not quitting + closeFloater(false); + } +} + +//virtual +void LLIMFloater::setDocked(bool docked, bool pop_on_undock) +{ + LLFloater::setDocked(docked); + mChiclet->setDockTongueVisible(docked); + if (docked) + { + S32 x, y; + mChiclet->localPointToScreen((mChiclet->getRect().getWidth())/2, 0, &x, &y); + translate(x - getRect().getCenterX(), DOCK_ICON_HEIGHT - getRect().mBottom); + } + else if (pop_on_undock) + { + // visually pop up a little bit to emphasize the undocking + translate(0, UNDOCK_LEAP_HEIGHT); + } +} + + +void LLIMFloater::onClose(bool app_quitting) +{ + mChiclet->setDockTongueVisible(false); + LLFloater::onClose(app_quitting); +} + +void LLIMFloater::onSlide() +{ + LLPanel* im_control_panel = getChild("panel_im_control_panel"); + im_control_panel->setVisible(!im_control_panel->getVisible()); + + getChild("slide_left_btn")->setVisible(im_control_panel->getVisible()); + getChild("slide_right_btn")->setVisible(!im_control_panel->getVisible()); +} + +//static +LLIMFloater* LLIMFloater::show(const LLUUID& session_id) +{ LLIMFloater* floater = get_if_there(sIMFloaterMap, session_id, (LLIMFloater*)NULL); if (floater == NULL) @@ -2078,28 +2243,25 @@ void LLIMFloater::show(const LLUUID& session_id, S32 center_x) { LLIMFloater* floater = (*iter).second; floater->setVisible(false); + floater->mChiclet->setDockTongueVisible(false); + } - //floater->setVisibleAndFrontmost(true); + floater->setVisibleAndFrontmost(true); - floater->updateMessages(session_id); - - floater->translate(center_x - floater->getRect().getCenterX(), gFloaterView->getRect().mBottom - floater->getRect().mBottom); + if (floater->isDocked()) + { + floater->mChiclet->setDockTongueVisible(true); + } + floater->updateMessages(); + return floater; } -void LLIMFloater::updateMessages(const LLUUID& session_id) +void LLIMFloater::updateMessages() { - LLTextEditor* text_editor = getChild("im_text", true, false); - - if (!text_editor) - { - llwarns << "Text editor not found! " << llendl; - return; - } - - std::list messages = LLIMModel::instance().getMessages(mSessionID, mIndex); + std::list messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1); if (messages.size()) { @@ -2112,10 +2274,45 @@ void LLIMFloater::updateMessages(const LLUUID& session_id) message << msg["from"].asString() << " : " << msg["time"].asString() << "\n " << msg["message"].asString() << "\n"; - mIndex = msg["index"].asInteger(); + mLastMessageIndex = msg["index"].asInteger(); } - text_editor->setText(message.str()); + mHistoryEditor->appendText(message.str(), false, false); + mHistoryEditor->setCursorAndScrollToEnd(); } } +// static +void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ) +{ + LLIMFloater* self= (LLIMFloater*) userdata; + self->mHistoryEditor->setCursorAndScrollToEnd(); +} + +// static +void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) +{ + LLIMFloater* self = (LLIMFloater*) userdata; + self->setTyping(FALSE); +} + +// static +void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) +{ + LLIMFloater* self = (LLIMFloater*)userdata; + std::string text = self->mInputEditor->getText(); + if (!text.empty()) + { + self->setTyping(TRUE); + } + else + { + // Deleting all text counts as stopping typing. + self->setTyping(FALSE); + } +} + +//just a stub for now +void LLIMFloater::setTyping(BOOL typing) +{ +} -- cgit v1.2.3