openclonk/src/gui/C4ChatDlg.h

199 lines
6.7 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2007-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2013-2016, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
// IRC client dialog
#ifndef INC_C4ChatDlg
#define INC_C4ChatDlg
#include "gui/C4Gui.h"
#include "network/C4InteractiveThread.h"
// a GUI control to chat in
class C4ChatControl : public C4GUI::Window, private C4InteractiveThread::Callback
{
private:
// one open channel or query
class ChatSheet : public C4GUI::Tabular::Sheet
{
public:
// one item in the nick list
class NickItem : public C4GUI::Window
{
private:
C4GUI::Icon *pStatusIcon; // status icon indicating channel status (e.g. operator)
C4GUI::Label *pNameLabel; // the nickname
bool fFlaggedExisting; // flagged for existance; used by user update func
int32_t iStatus;
public:
NickItem(class C4Network2IRCUser *pByUser);
protected:
void UpdateOwnPos() override;
public:
const char *GetNick() const { return pNameLabel->GetText(); }
int32_t GetStatus() const { return iStatus; }
void Update(class C4Network2IRCUser *pByUser);
void SetFlaggedExisting(bool fToVal) { fFlaggedExisting = fToVal; }
bool IsFlaggedExisting() const { return fFlaggedExisting; }
static int32_t SortFunc(const C4GUI::Element *pEl1, const C4GUI::Element *pEl2, void *);
};
enum SheetType { CS_Server, CS_Channel, CS_Query };
private:
C4ChatControl *pChatControl;
C4GUI::TextWindow *pChatBox;
C4GUI::ListBox *pNickList;
C4GUI::WoodenLabel *pInputLbl;
C4GUI::Edit *pInputEdit;
int32_t iBackBufferIndex; // chat message history index
SheetType eType;
StdStrBuf sIdent;
bool fHasUnread;
StdStrBuf sChatTitle; // topic for channels; name+ident for queries; server name for server sheet
C4KeyBinding *pKeyHistoryUp, *pKeyHistoryDown; // keys used to scroll through chat history
public:
ChatSheet(C4ChatControl *pChatControl, const char *szTitle, const char *szIdent, SheetType eType);
~ChatSheet() override;
C4GUI::Edit *GetInputEdit() const { return pInputEdit; }
SheetType GetSheetType() const { return eType; }
const char *GetIdent() const { return sIdent.getData(); }
void SetIdent(const char *szToIdent) { sIdent.Copy(szToIdent); }
const char *GetChatTitle() const { return sChatTitle.getData(); }
void SetChatTitle(const char *szNewTitle) { sChatTitle.Copy(szNewTitle); }
void AddTextLine(const char *szText, uint32_t dwClr);
void DoError(const char *szError);
void Update(bool fLock);
void UpdateUsers(C4Network2IRCUser *pUsers);
void ResetUnread(); // mark messages as read
protected:
void UpdateSize() override;
void OnShown(bool fByUser) override;
void UserClose() override; // user pressed close button: Close queries, part channels, etc.
C4GUI::Edit::InputResult OnChatInput(C4GUI::Edit *edt, bool fPasting, bool fPastingMore);
bool KeyHistoryUpDown(bool fUp);
void OnNickDblClick(class C4GUI::Element *pEl);
private:
NickItem *GetNickItem(const char *szByNick);
NickItem *GetFirstNickItem() { return pNickList ? static_cast<NickItem *>(pNickList->GetFirst()) : nullptr; }
NickItem *GetNextNickItem(NickItem *pPrev) { return static_cast<NickItem *>(pPrev->GetNext()); }
};
private:
C4GUI::Tabular *pTabMain, *pTabChats;
// login controls
C4GUI::Label *pLblLoginNick, *pLblLoginPass, *pLblLoginRealName, *pLblLoginChannel;
C4GUI::Edit *pEdtLoginNick, *pEdtLoginPass, *pEdtLoginRealName, *pEdtLoginChannel;
C4GUI::Button *pBtnLogin;
StdStrBuf sTitle;
C4GUI::BaseInputCallback *pTitleChangeBC;
C4Network2IRCClient *pIRCClient;
bool fInitialMessagesReceived; // set after initial update call, which fetches all messages. Subsequent calls fetch only unread messages
public:
C4ChatControl(C4Network2IRCClient *pIRC);
~C4ChatControl() override;
protected:
void UpdateSize() override;
C4GUI::Edit::InputResult OnLoginDataEnter(C4GUI::Edit *edt, bool fPasting, bool fPastingMore); // advance focus when user presses enter in one of the login edits
void OnConnectBtn(C4GUI::Control *btn); // callback: connect button pressed
public:
virtual class C4GUI::Control *GetDefaultControl();
C4Network2IRCClient *getIRCClient() { return pIRCClient; }
void SetTitleChangeCB(C4GUI::BaseInputCallback *pNewCB);
virtual void OnShown(); // callback when shown
void UpdateShownPage();
void Update();
void UpdateTitle();
bool DlgEnter();
void OnSec1Timer() { Update(); } // timer proc
bool ProcessInput(const char *szInput, ChatSheet *pChatSheet); // process chat input - return false if no more pasting is to be done (i.e., on /quit or /part in channel)
const char *GetTitle() { return sTitle.getData(); }
void UserQueryQuit();
ChatSheet *OpenQuery(const char *szForNick, bool fSelect, const char *szIdentFallback);
private:
static bool IsServiceName(const char *szName);
ChatSheet *GetActiveChatSheet();
ChatSheet *GetSheetByTitle(const char *szTitle, C4ChatControl::ChatSheet::SheetType eType);
ChatSheet *GetSheetByIdent(const char *szIdent, C4ChatControl::ChatSheet::SheetType eType);
ChatSheet *GetServerSheet();
void ClearChatSheets();
// IRC event hook
void OnThreadEvent(C4InteractiveEventType eEvent, void *pEventData) override { if (pEventData == pIRCClient) Update(); }
};
// container dialog for the C4ChatControl
class C4ChatDlg : public C4GUI::Dialog
{
private:
static C4ChatDlg *pInstance;
class C4ChatControl *pChatCtrl;
C4GUI::Button *pBtnClose;
public:
C4ChatDlg();
~C4ChatDlg() override;
static C4ChatDlg *ShowChat();
static void StopChat();
static bool IsChatActive();
static bool IsChatEnabled();
static bool ToggleChat();
protected:
// default control to be set if unprocessed keyboard input has been detected
class C4GUI::Control *GetDefaultControl() override;
// true for dialogs that should span the whole screen
// not just the mouse-viewport
bool IsFreePlaceDialog() override { return true; }
// true for dialogs that receive keyboard input even in shared mode
bool IsExclusiveDialog() override { return true; }
// for custom placement procedures; should call SetPos
bool DoPlacement(C4GUI::Screen *pOnScreen, const C4Rect &rPreferredDlgRect) override;
void OnClosed(bool fOK) override; // callback when dlg got closed
void OnShown() override; // callback when shown - should not delete the dialog
void UpdateSize() override;
void OnExitBtn(C4GUI::Control *btn); // callback: exit button pressed
void OnChatTitleChange(const StdStrBuf &sNewTitle);
};
#endif // INC_C4ChatDlg