1
0
forked from 0ad/0ad
0ad/source/gui/CInput.h

167 lines
5.0 KiB
C++

/*
GUI Object - Input [box]
by Gustav Larsson
gee@pyro.nu
--Overview--
GUI Object representing a text field you can edit.
--More info--
Check GUI.h
*/
#ifndef CInput_H
#define CInput_H
//--------------------------------------------------------
// Includes / Compiler directives
//--------------------------------------------------------
#include "GUI.h"
// TODO Gee: Remove
class IGUIScrollBar;
//--------------------------------------------------------
// Macros
//--------------------------------------------------------
//--------------------------------------------------------
// Types
//--------------------------------------------------------
//--------------------------------------------------------
// Declarations
//--------------------------------------------------------
/**
* @author Gustav Larsson
*
* Text field where you can input and edit the text.
*
* It doesn't use IGUITextOwner, because we don't need
* any other features than word-wrapping, and we need to be
* able to rapidly change the string.
*
* @see IGUIObject
*/
class CInput : public IGUIScrollBarOwner
{
GUI_OBJECT(CInput)
protected: // forwards
struct SRow;
public:
CInput();
virtual ~CInput();
virtual void ResetStates() { IGUIScrollBarOwner::ResetStates(); }
// Check where the mouse is hovering, and get the appropriate text position.
// return is the text-position index.
// const in philosophy, but I need to retrieve the caption in a non-const way.
int GetMouseHoveringTextPosition();
// Same as above, but only on one row in X, and a given value, not the mouse's
// wanted is filled with x if the row didn't extend as far as we
int GetXTextPosition(const std::list<SRow>::iterator &c, const float &x, float &wanted);
protected:
/**
* Handle Messages
*
* @param Message GUI Message
*/
virtual void HandleMessage(const SGUIMessage &Message);
/**
* Handle events manually to catch keyboard inputting.
*/
virtual InReaction ManuallyHandleEvent(const SDL_Event* ev);
// void InsertMessage(const wchar_t* szMessage, ...);
// void InsertChar(const int szChar, const wchar_t cooked);
/**
* Draws the Text
*/
virtual void Draw();
// Calculate m_CharacterPosition
// the main task for this function is to perfom word-wrapping
// You input from which character it has been changed, because
// if we add a character to the very last end, we don't want
// process everything all over again! Also notice you can
// specify a 'to' also, it will only be used though if a '\n'
// appears, because then the word-wrapping won't change after
// that.
void UpdateText(int from=0, int to_before=-1, int to_after=-1);
// Delete the current selection. Also places the pointer at the
// crack between the two segments kept.
void DeleteCurSelection();
// Is text selected? It can be denote two ways, m_iBufferPos_Tail
// being -1 or the same as m_iBufferPos. This makes for clearer
// code.
bool SelectingText() const;
// Get area of where text can be drawn.
float GetTextAreaWidth();
// Called every time the auto-scrolling should be checked.
void UpdateAutoScroll();
protected:
// Cursor position
// (the second one is for selection of larger areas, -1 if not used)
// A note on 'Tail', it was first called 'To', and the natural order
// of X and X_To was X then X_To. Now Tail is called so, because it
// can be placed both before and after, but the important things is
// that m_iBufferPos is ALWAYS where the edit pointer is. Yes, there
// is an edit pointer even though you select a larger area. For instance
// if you want to resize the selection with Shift+Left/Right, there
// are always two ways a selection can look. Check any OS GUI and you'll
// see.
int m_iBufferPos,
m_iBufferPos_Tail;
// the outer vector is lines, and the inner is X positions
// in a row. So that we can determine where characters are
// placed. It's important because we need to know where the
// pointer should be placed when the input control is pressed.
struct SRow
{
int m_ListStart; // Where does the Row starts
std::vector<float> m_ListOfX; // List of X values for each character.
};
// List of rows, list because I use a lot of iterators, and change
// its size continuously, it's easier and safer if I know the
// iterators never gets invalidated.
// For one-liners, only one row is used.
std::list< SRow > m_CharacterPositions;
// *** Things for a multi-lined input control *** //
// This is when you change row with up/down, and the row you jump
// to doesn't have anything at that X position, then it will
// keep the WantedX position in mind when switching to the next
// row. It will keep on being used until it reach a row which meets
// the requirements.
// 0.0f means not in use.
float m_WantedX;
// If we are in the process of selecting a larger selection of text
// using the mouse click (hold) and drag, this is true.
bool m_SelectingText;
// *** Things for one-line input control *** //
float m_HorizontalScroll;
};
#endif