/* * OpenClonk, http://www.openclonk.org * * Copyright (c) 2005-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. */ // handles input dialogs, last-message-buffer, MessageBoard-commands #ifndef INC_C4MessageInput #define INC_C4MessageInput #include "gui/C4Gui.h" #include "object/C4ObjectPtr.h" const int32_t C4MSGB_BackBufferMax = 20; // chat input dialog class C4ChatInputDialog : public C4GUI::InputDialog { private: typedef C4GUI::InputDialog BaseClass; class C4KeyBinding *pKeyHistoryUp, *pKeyHistoryDown, *pKeyAbort, *pKeyNickComplete, *pKeyPlrControl, *pKeyGamepadControl, *pKeyBackClose; bool fObjInput; // input queried by script? bool fUppercase; // script input converted to uppercase class C4Object *pTarget; // target object for script callback int32_t iPlr; // target player for script callback // last message lookup int32_t BackIndex; bool fProcessed; // set if chat input has been processed static C4ChatInputDialog *pInstance; // singleton-instance private: bool KeyHistoryUpDown(bool fUp); bool KeyCompleteNick(); // complete nick at cursor pos of edit bool KeyPlrControl(const C4KeyCodeEx &key); bool KeyGamepadControlDown(const C4KeyCodeEx &key); bool KeyGamepadControlUp(const C4KeyCodeEx &key); bool KeyGamepadControlPressed(const C4KeyCodeEx &key); bool KeyBackspaceClose(); // close if chat text box is empty (on backspace) protected: // chat input callback C4GUI::Edit::InputResult OnChatInput(C4GUI::Edit *edt, bool fPasting, bool fPastingMore); void OnChatCancel(); void OnClosed(bool fOK) override; const char *GetID() override { return "ChatDialog"; } public: C4ChatInputDialog(bool fObjInput, C4Object *pScriptTarget, bool fUpperCase, bool fTeam, int32_t iPlr, const StdStrBuf &rsInputQuery); // ctor - construct by screen ratios ~C4ChatInputDialog() override; // place on top of normal dialogs int32_t GetZOrdering() override { return C4GUI_Z_CHAT; } // align by screen, not viewport bool IsFreePlaceDialog() override { return true; } // place more to the bottom of the screen bool IsBottomPlacementDialog() override { return true; } // true for dialogs that receive full keyboard and mouse input even in shared mode bool IsExclusiveDialog() override { return true; } // don't enable mouse just for this dlg bool IsMouseControlled() override { return false; } // usually processed by edit; // but may reach this if the user managed to deselect the edit control bool OnEnter() override { OnChatInput(pEdit, false, false); return true; } static bool IsShown() { return !!pInstance; } // external query fn whether dlg is visible static C4ChatInputDialog *GetInstance() { return pInstance; } bool IsScriptQueried() const { return fObjInput; } class C4Object *GetScriptTargetObject() const { return pTarget; } int32_t GetScriptTargetPlayer() const { return iPlr; } }; class C4MessageBoardCommand { public: C4MessageBoardCommand(); public: char Name[C4MaxName + 1]; char Script[_MAX_FNAME+30+1]; C4MessageBoardCommand *Next; }; class C4MessageInput { public: C4MessageInput() { Default(); } ~C4MessageInput() { Clear(); } void Default(); void Clear(); bool Init(); private: // last input messages to be accessed via 'up'/'down' in input dialog char BackBuffer[C4MSGB_BackBufferMax][C4MaxMessage]; // MessageBoard-commands private: class C4MessageBoardCommand *pCommands{nullptr}; public: void AddCommand(const char *strCommand, const char *strScript); class C4MessageBoardCommand *GetCommand(const char *strName); // Input public: bool CloseTypeIn(); bool StartTypeIn(bool fObjInput = false, C4Object *pObj = nullptr, bool fUpperCase = false, bool fTeam = false, int32_t iPlr = -1, const StdStrBuf &rsInputQuery = StdStrBuf()); bool KeyStartTypeIn(bool fTeam); bool ToggleTypeIn(); bool IsTypeIn(); C4ChatInputDialog *GetTypeIn() { return C4ChatInputDialog::GetInstance(); } void StoreBackBuffer(const char *szMessage); const char *GetBackBuffer(int32_t iIndex); bool ProcessInput(const char *szText); bool ProcessCommand(const char *szCommand); public: void ClearPointers(C4Object *pObj); void AbortMsgBoardQuery(C4Object *pObj, int32_t iPlr); friend class C4ChatInputDialog; }; extern C4MessageInput MessageInput; // script query to ask a player for a string class C4MessageBoardQuery { public: C4ObjectPtr CallbackObj; // callback target object StdStrBuf sInputQuery; // question being asked to the player bool fAnswered{false}; // if set, an answer packet is in the queue (NOSAVE, as the queue isn't saved either!) bool fIsUppercase{false}; // if set, any input is converted to uppercase be4 sending to script // linked list to allow for multiple queries C4MessageBoardQuery *pNext{nullptr}; // ctors C4MessageBoardQuery(C4Object *pCallbackObj, const StdStrBuf &rsInputQuery, bool fIsUppercase) : CallbackObj(pCallbackObj), fIsUppercase(fIsUppercase), pNext(nullptr) { sInputQuery.Copy(rsInputQuery); } C4MessageBoardQuery() : CallbackObj(nullptr) {} // use default copy ctor // compilation void CompileFunc(StdCompiler *pComp); }; #endif // INC_C4MessageInput