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); } }
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; }