Beispiel #1
0
	IntCoord Window::_getActionScale(Widget* _widget)
	{
		if (_widget->isUserString("Scale"))
		{
			IntCoord result = IntCoord::parse(_widget->getUserString("Scale"));

			if (result == IntCoord(1, 1, 0, 0) && !mMovable)
				result.clear();

			return result;
		}
		else if (_widget->isUserString("Action"))
		{
			const std::string& action = _widget->getUserString("Action");
			if (action == "Move")
			{
				if (mMovable)
					return IntCoord(1, 1, 0, 0);
				else
					return IntCoord();
			}

			IntCoord coord;
			Align align = Align::parse(action);

			if (align.isLeft())
			{
				coord.left = 1;
				coord.width = -1;
			}
			else if (align.isRight())
			{
				coord.width = 1;
			}

			if (align.isTop())
			{
				coord.top = 1;
				coord.height = -1;
			}
			else if (align.isBottom())
			{
				coord.height = 1;
			}

			return coord;
		}

		return IntCoord();
	}
	void ScrollViewBase::updateScrollPosition()
	{
		// размер контекста
		IntSize contentSize = getContentSize();
		// текущее смещение контекста
		IntPoint contentPoint = getContentPosition();
		// расчетное смещение
		IntPoint offset = contentPoint;

		IntSize viewSize = getViewSize();

		Align align = getContentAlign();

		if (contentSize.width > viewSize.width)
		{
			// максимальный выход влево
			if ((offset.left + viewSize.width) > contentSize.width)
			{
				offset.left = contentSize.width - viewSize.width;
			}
			// максимальный выход вправо
			else if (offset.left < 0)
			{
				offset.left = 0;
			}
		}
		else
		{
			if (align.isLeft())
			{
				offset.left = 0;
			}
			else if (align.isRight())
			{
				offset.left = contentSize.width - viewSize.width;
			}
			else
			{
				offset.left = (contentSize.width - viewSize.width) / 2;
			}
		}

		if (contentSize.height > viewSize.height)
		{
			// максимальный выход вверх
			if ((offset.top + viewSize.height) > contentSize.height)
			{
				offset.top = contentSize.height - viewSize.height;
			}
			// максимальный выход вниз
			else if (offset.top < 0)
			{
				offset.top = 0;
			}
		}
		else
		{
			if (align.isTop())
			{
				offset.top = 0;
			}
			else if (align.isBottom())
			{
				offset.top = contentSize.height - viewSize.height;
			}
			else
			{
				offset.top = (contentSize.height - viewSize.height) / 2;
			}
		}

		if (offset != contentPoint)
		{
			if (nullptr != mVScroll) mVScroll->setScrollPosition(offset.top);
			if (nullptr != mHScroll) mHScroll->setScrollPosition(offset.left);
			setContentPosition(offset);
		}
	}
Beispiel #3
0
	void TextView::update(const UString& _text, IFont* _font, int _height, Align _align, VertexColourType _format, int _maxheight)
	{
		mFontHeight = _height;

		// массив дл¤ быстрой конвертации цветов
		static const char convert_colour[64] =
		{
			0,  1,  2,  3,  4,  5,  6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
			0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0
		};

		mViewSize.clear();

		RollBackPoint roll_back;
		IntSize result;
		int width = 0;
		size_t count = 0;
		mLength = 0;
		mLineInfo.clear();
		LineInfo line_info;
		int font_height = _font->getDefaultHeight();

		UString::const_iterator end = _text.end();
		UString::const_iterator index = _text.begin();

		/*if (index == end)
			return;*/

		result.height += _height;

		for (; index != end; ++index)
		{
			Char character = *index;

			// нова¤ строка
			if (character == FontCodeType::CR
				|| character == FontCodeType::NEL
				|| character == FontCodeType::LF)
			{
				if (character == FontCodeType::CR)
				{
					UString::const_iterator peeki = index;
					++peeki;
					if ((peeki != end) && (*peeki == FontCodeType::LF))
						index = peeki; // skip both as one newline
				}

				line_info.width = width;
				line_info.count = count;
				mLength += line_info.count + 1;

				result.height += _height;
				if (result.width < width)
					result.width = width;
				width = 0;
				count = 0;

				mLineInfo.push_back(line_info);
				line_info.clear();

				// отмен¤ем откат
				roll_back.clear();

				continue;
			}
			// тег
			else if (character == L'#')
			{
				// берем следующий символ
				++ index;
				if (index == end)
				{
					--index;    // это защита
					continue;
				}

				character = *index;
				// если два подр¤д, то рисуем один шарп, если нет то мен¤ем цвет
				if (character != L'#')
				{
					// парсим первый символ
					uint32 colour = convert_colour[(character-48) & 0x3F];

					// и еще п¤ть символов после шарпа
					for (char i = 0; i < 5; i++)
					{
						++ index;
						if (index == end)
						{
							--index;    // это защита
							continue;
						}
						colour <<= 4;
						colour += convert_colour[ ((*index) - 48) & 0x3F ];
					}

					// если нужно, то мен¤ем красный и синий компоненты
					texture_utility::convertColour(colour, _format);

					line_info.simbols.push_back( CharInfo(colour) );

					continue;
				}
			}

			GlyphInfo* info = _font->getGlyphInfo(character);
			if (FontCodeType::Space == character)
			{
				roll_back.set(line_info.simbols.size(), index, count, width);
			}
			else if (FontCodeType::Tab == character)
			{
				roll_back.set(line_info.simbols.size(), index, count, width);
			}

			int char_width = info->width;
			if (font_height != _height)
			{
				char_width = char_width * _height / font_height;
				if (!char_width) char_width = 1;
			}

			// перенос слов
			if (_maxheight != -1
				&& (width + char_width) > _maxheight
				&& !roll_back.empty())
			{
				// откатываем до последнего пробела
				width = roll_back.getLenght();
				count = roll_back.getCount();
				index = roll_back.getTextIter();
				line_info.simbols.erase(line_info.simbols.begin() + roll_back.getPosition(), line_info.simbols.end());

				// запоминаем место отката, как полную строку
				line_info.width = width;
				line_info.count = count;
				mLength += line_info.count + 1;

				result.height += _height;
				if (result.width < width)
					result.width = width;
				width = 0;
				count = 0;

				mLineInfo.push_back(line_info);
				line_info.clear();

				// отмен¤ем откат
				roll_back.clear();

				continue;
			}

			line_info.simbols.push_back(CharInfo(info->uvRect, char_width));
			width += char_width;
			count ++;
		}

		line_info.width = width;
		line_info.count = count;
		mLength += line_info.count;

		mLineInfo.push_back(line_info);

		if (result.width < width)
			result.width = width;

		// теперь выравниванием строки
		for (VectorLineInfo::iterator line = mLineInfo.begin(); line != mLineInfo.end(); ++line)
		{
			if (_align.isRight())
				line->offset = result.width - line->width;
			else if (_align.isHCenter())
				line->offset = (result.width - line->width) / 2;
		}

		mViewSize = result;
	}