/*
* Copyright 2010 OpenXcom Developers.
*
* This file is part of OpenXcom.
*
* OpenXcom is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenXcom is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenXcom. If not, see .
*/
#include "TextEdit.h"
#include
#include "../Engine/Action.h"
#include "../Engine/Font.h"
#include "../Engine/Timer.h"
namespace OpenXcom
{
/**
* Sets up a blank text edit with the specified size and position.
* @param width Width in pixels.
* @param height Height in pixels.
* @param x X position in pixels.
* @param y Y position in pixels.
*/
TextEdit::TextEdit(int width, int height, int x, int y) : InteractiveSurface(width, height, x, y), _value(L""), _blink(true), _ascii('A')
{
_validButton = SDL_BUTTON_LEFT;
_text = new Text(width, height, 0, 0);
_timer = new Timer(100);
_timer->onTimer((SurfaceHandler)&TextEdit::blink);
}
/**
* Deletes contents.
*/
TextEdit::~TextEdit()
{
delete _text;
delete _timer;
}
/**
* Starts the blinking animation when
* the text edit is focused.
*/
void TextEdit::focus()
{
InteractiveSurface::focus();
_blink = true;
_timer->start();
draw();
}
/**
* Changes the text edit to use the big-size font.
*/
void TextEdit::setBig()
{
_text->setBig();
}
/**
* Changes the text edit to use the small-size font.
*/
void TextEdit::setSmall()
{
_text->setSmall();
}
/**
* Changes the various fonts for the text edit to use.
* The different fonts need to be passed in advance since the
* text size can change mid-text.
* @param big Pointer to large-size font.
* @param small Pointer to small-size font.
*/
void TextEdit::setFonts(Font *big, Font *small)
{
_text->setFonts(big, small);
}
/**
* Changes the string displayed on screen.
* @param text Text string.
*/
void TextEdit::setText(const std::wstring &text)
{
_value = text;
draw();
}
/**
* Returns the string displayed on screen.
* @return Text string.
*/
std::wstring TextEdit::getText() const
{
return _value;
}
/**
* Enables/disables text wordwrapping. When enabled, lines of
* text are automatically split to ensure they stay within the
* drawing area, otherwise they simply go off the edge.
* @param wrap Wordwrapping setting.
*/
void TextEdit::setWordWrap(bool wrap)
{
_text->setWordWrap(wrap);
}
/**
* Enables/disables color inverting. Mostly used to make
* button text look pressed along with the button.
* @param invert Invert setting.
*/
void TextEdit::setInvert(bool invert)
{
_text->setInvert(invert);
}
/**
* Changes the way the text is aligned horizontally
* relative to the drawing area.
* @param align Horizontal alignment.
*/
void TextEdit::setAlign(TextHAlign align)
{
_text->setAlign(align);
}
/**
* Changes the way the text is aligned vertically
* relative to the drawing area.
* @param valign Vertical alignment.
*/
void TextEdit::setVerticalAlign(TextVAlign valign)
{
_text->setVerticalAlign(valign);
}
/**
* Changes the color used to render the text. Unlike regular graphics,
* fonts are greyscale so they need to be assigned a specific position
* in the palette to be displayed.
* @param color Color value.
*/
void TextEdit::setColor(Uint8 color)
{
_text->setColor(color);
}
/**
* Returns the color used to render the text.
* @return Color value.
*/
Uint8 TextEdit::getColor() const
{
return _text->getColor();
}
/**
* Replaces a certain amount of colors in the text edit's palette.
* @param colors Pointer to the set of colors.
* @param firstcolor Offset of the first color to replace.
* @param ncolors Amount of colors to replace.
*/
void TextEdit::setPalette(SDL_Color *colors, int firstcolor, int ncolors)
{
Surface::setPalette(colors, firstcolor, ncolors);
_text->setPalette(colors, firstcolor, ncolors);
}
/**
* Keeps the animation timers running.
*/
void TextEdit::think()
{
_timer->think(0, this);
}
/**
* Plays the blinking animation when the
* text edit is focused.
*/
void TextEdit::blink()
{
_blink = !_blink;
draw();
}
/**
* Adds a flashing * to the end of the text
* to show when it's focused and editable.
*/
void TextEdit::draw()
{
std::wstringstream ss;
#ifdef DINGOO
ss << _value << _ascii;
#else
ss << _value << "*";
#endif
if (_isFocused && _blink)
_text->setText(ss.str());
else
_text->setText(_value);
clear();
_text->blit(this);
}
/**
* Checks if adding a certain character to
* the text edit will exceed the maximum width.
* Used to make sure user input stays within bounds.
* @param c Character to add.
* @return True if it exceeds, False if it doesn't.
*/
bool TextEdit::exceedsMaxWidth(wchar_t c)
{
int w = 0;
std::wstring s = _value;
s += c;
s += '*';
for (std::wstring::iterator i = s.begin(); i < s.end(); i++)
w += _text->getFont()->getChar(*i)->getCrop()->w + _text->getFont()->getSpacing();
if (w > getWidth())
return true;
else
return false;
}
/**
* Focuses the text edit when it's pressed on.
* @param action Pointer to an action.
* @param state State that the action handlers belong to.
*/
void TextEdit::mousePress(Action *action, State *state)
{
focus();
InteractiveSurface::mousePress(action, state);
}
/**
* Changes the text edit according to keyboard input, and
* unfocuses the text if Enter is pressed.
* @param action Pointer to an action.
* @param state State that the action handlers belong to.
*/
void TextEdit::keyboardPress(Action *action, State *state)
{
switch (action->getDetails()->key.keysym.sym)
{
#ifdef DINGOO
case SDLK_UP:
_ascii++;
if (_ascii > '~')
_ascii = ' ';
break;
case SDLK_DOWN:
_ascii--;
if (_ascii < ' ')
_ascii = '~';
break;
case SDLK_RIGHT:
if (!exceedsMaxWidth(_ascii))
_value += _ascii;
break;
case SDLK_LEFT:
#endif
case SDLK_BACKSPACE:
if (_value.length() > 0)
_value.resize(_value.length() - 1);
break;
case SDLK_RETURN:
_isFocused = false;
_blink = false;
_timer->stop();
break;
default:
if (action->getDetails()->key.keysym.unicode != 0)
{
if (action->getDetails()->key.keysym.unicode >= ' ' && action->getDetails()->key.keysym.unicode <= '~' && !exceedsMaxWidth((wchar_t)action->getDetails()->key.keysym.unicode))
_value += (wchar_t)action->getDetails()->key.keysym.unicode;
}
}
draw();
InteractiveSurface::keyboardPress(action, state);
}
}