int ShapeResult::RunInfo::characterIndexForXPosition(float targetX) const
{
    ASSERT(targetX <= m_width);
    float currentX = 0;
    float currentAdvance = m_glyphData[0].advance;
    unsigned glyphIndex = 0;

    // Sum up advances that belong to the first character.
    while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].characterIndex == m_glyphData[glyphIndex + 1].characterIndex)
        currentAdvance += m_glyphData[++glyphIndex].advance;
    currentAdvance = currentAdvance / 2.0;
    if (targetX <= currentAdvance)
        return rtl() ? m_numCharacters : 0;

    currentX = currentAdvance;
    ++glyphIndex;
    while (glyphIndex < m_numGlyphs) {
        unsigned prevCharacterIndex = m_glyphData[glyphIndex - 1].characterIndex;
        float prevAdvance = currentAdvance;
        currentAdvance = m_glyphData[glyphIndex].advance;
        while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].characterIndex == m_glyphData[glyphIndex + 1].characterIndex)
            currentAdvance += m_glyphData[++glyphIndex].advance;
        currentAdvance = currentAdvance / 2.0;
        float nextX = currentX + prevAdvance + currentAdvance;
        if (currentX <= targetX && targetX <= nextX)
            return rtl() ? prevCharacterIndex : m_glyphData[glyphIndex].characterIndex;
        currentX = nextX;
        ++glyphIndex;
    }

    return rtl() ? 0 : m_numCharacters;
}
Exemple #2
0
int HarfBuzzShaper::HarfBuzzRun::characterIndexForXPosition(float targetX)
{
    ASSERT(targetX <= m_width);
    float currentX = 0;
    float currentAdvance = m_advances[0];
    unsigned glyphIndex = 0;

    // Sum up advances that belong to a character.
    while (glyphIndex < m_numGlyphs - 1 && m_glyphToCharacterIndexes[glyphIndex] == m_glyphToCharacterIndexes[glyphIndex + 1])
        currentAdvance += m_advances[++glyphIndex];
    currentAdvance = currentAdvance / 2.0;
    if (targetX <= currentAdvance)
        return rtl() ? m_numCharacters : 0;

    ++glyphIndex;
    while (glyphIndex < m_numGlyphs) {
        unsigned prevCharacterIndex = m_glyphToCharacterIndexes[glyphIndex - 1];
        float prevAdvance = currentAdvance;
        currentAdvance = m_advances[glyphIndex];
        while (glyphIndex < m_numGlyphs - 1 && m_glyphToCharacterIndexes[glyphIndex] == m_glyphToCharacterIndexes[glyphIndex + 1])
            currentAdvance += m_advances[++glyphIndex];
        currentAdvance = currentAdvance / 2.0;
        float nextX = currentX + prevAdvance + currentAdvance;
        if (currentX <= targetX && targetX <= nextX)
            return rtl() ? prevCharacterIndex : m_glyphToCharacterIndexes[glyphIndex];
        currentX = nextX;
        prevAdvance = currentAdvance;
        ++glyphIndex;
    }

    return rtl() ? 0 : m_numCharacters;
}
void Menu::handleKeyPress(int key) {
	if (key == Qt::Key_Enter || key == Qt::Key_Return) {
		itemPressed(TriggeredSource::Keyboard);
		return;
	}
	if (key == (rtl() ? Qt::Key_Left : Qt::Key_Right)) {
		if (_selected >= 0 && _actionsData[_selected].hasSubmenu) {
			itemPressed(TriggeredSource::Keyboard);
			return;
		} else if (_selected < 0 && !_actions.isEmpty()) {
			_mouseSelection = false;
			setSelected(0);
		}
	}
	if ((key != Qt::Key_Up && key != Qt::Key_Down) || _actions.size() < 1) return;

	auto delta = (key == Qt::Key_Down ? 1 : -1), start = _selected;
	if (start < 0 || start >= _actions.size()) {
		start = (delta > 0) ? (_actions.size() - 1) : 0;
	}
	auto newSelected = start;
	do {
		newSelected += delta;
		if (newSelected < 0) {
			newSelected += _actions.size();
		} else if (newSelected >= _actions.size()) {
			newSelected -= _actions.size();
		}
	} while (newSelected != start && (!_actions[newSelected]->isEnabled() || _actions[newSelected]->isSeparator()));

	if (_actions[newSelected]->isEnabled() && !_actions[newSelected]->isSeparator()) {
		_mouseSelection = false;
		setSelected(newSelected);
	}
}
void PeerListWidget::updateSelection() {
	auto selected = -1;
	auto selectedKick = false;

	auto mouse = mapFromGlobal(_mousePosition);
	if (rtl()) mouse.setX(width() - mouse.x());
	auto left = getListLeft();
	auto top = getListTop();
	auto memberRowWidth = rowWidth();
	if (mouse.x() >= left && mouse.x() < left + memberRowWidth && mouse.y() >= top) {
		selected = (mouse.y() - top) / _st.height;
		if (selected >= _items.size()) {
			selected = -1;
		} else if (_items[selected]->hasRemoveLink) {
			int skip = _st.photoPosition.x();
			int nameLeft = left + _st.namePosition.x();
			int nameTop = top + _selected * _st.height + _st.namePosition.y();
			int nameWidth = memberRowWidth - _st.namePosition.x() - skip;
			if (mouse.x() >= nameLeft + nameWidth - _removeWidth && mouse.x() < nameLeft + nameWidth) {
				if (mouse.y() >= nameTop && mouse.y() < nameTop + st::normalFont->height) {
					selectedKick = true;
				}
			}
		}
	}

	setSelected(selected, selectedKick);
}
int HarfBuzzShaper::HarfBuzzRun::characterIndexForXPosition(int targetX)
{
    ASSERT(static_cast<unsigned>(targetX) <= m_width);
    int currentX = 0;
    float prevAdvance = 0;
    for (unsigned i = 0; i < m_numGlyphs; ++i) {
        float currentAdvance = m_advances[i] / 2.0;
        int nextX = currentX + roundf(prevAdvance + currentAdvance);
        if (currentX <= targetX && targetX <= nextX)
            return m_glyphToCharacterIndex[i] + (rtl() ? 1 : 0);
        currentX = nextX;
        prevAdvance = currentAdvance;
    }

    return rtl() ? 0 : m_numCharacters;
}
float ShapeResult::RunInfo::xPositionForVisualOffset(unsigned offset) const
{
    ASSERT(offset < m_numCharacters);
    if (rtl())
        offset = m_numCharacters - offset - 1;
    return xPositionForOffset(offset);
}
// Advance to the next script run, returning false when the end of the
// TextRun has been reached.
bool ComplexTextController::nextScriptRun()
{
    // Ensure we're not pointing at the small caps buffer.
    m_item.string = m_run.characters();

    if (!hb_utf16_script_run_next(0, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun))
        return false;

    // It is actually wrong to consider script runs at all in this code.
    // Other WebKit code (e.g. Mac) segments complex text just by finding
    // the longest span of text covered by a single font.
    // But we currently need to call hb_utf16_script_run_next anyway to fill
    // in the harfbuzz data structures to e.g. pick the correct script's shaper.
    // So we allow that to run first, then do a second pass over the range it
    // found and take the largest subregion that stays within a single font.
    m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData;
    unsigned endOfRun;
    for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) {
        const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false).fontData;
        if (nextFontData != m_currentFontData)
            break;
    }
    m_item.item.length = endOfRun;
    m_indexOfNextScriptRun = m_item.item.pos + endOfRun;

    setupFontForScriptRun();
    shapeGlyphs();
    setGlyphXPositions(rtl());

    return true;
}
float ShapeResult::RunInfo::xPositionForOffset(unsigned offset) const
{
    ASSERT(offset <= m_numCharacters);
    unsigned glyphIndex = 0;
    float position = 0;
    if (rtl()) {
        while (glyphIndex < m_numGlyphs && m_glyphData[glyphIndex].characterIndex > offset) {
            position += m_glyphData[glyphIndex].advance;
            ++glyphIndex;
        }
        // For RTL, we need to return the right side boundary of the character.
        // Add advance of glyphs which are part of the character.
        while (glyphIndex < m_numGlyphs - 1 && m_glyphData[glyphIndex].characterIndex == m_glyphData[glyphIndex + 1].characterIndex) {
            position += m_glyphData[glyphIndex].advance;
            ++glyphIndex;
        }
        position += m_glyphData[glyphIndex].advance;
    } else {
        while (glyphIndex < m_numGlyphs && m_glyphData[glyphIndex].characterIndex < offset) {
            position += m_glyphData[glyphIndex].advance;
            ++glyphIndex;
        }
    }
    return position;
}
Exemple #9
0
float HarfBuzzShaper::HarfBuzzRun::xPositionForOffset(unsigned offset)
{
    ASSERT(offset < m_numCharacters);
    unsigned glyphIndex = 0;
    float position = 0;
    if (rtl()) {
        while (glyphIndex < m_numGlyphs && m_glyphToCharacterIndexes[glyphIndex] > offset) {
            position += m_advances[glyphIndex];
            ++glyphIndex;
        }
        // For RTL, we need to return the right side boundary of the character.
        // Add advance of glyphs which are part of the character.
        while (glyphIndex < m_numGlyphs - 1 && m_glyphToCharacterIndexes[glyphIndex] == m_glyphToCharacterIndexes[glyphIndex + 1]) {
            position += m_advances[glyphIndex];
            ++glyphIndex;
        }
        position += m_advances[glyphIndex];
    } else {
        while (glyphIndex < m_numGlyphs && m_glyphToCharacterIndexes[glyphIndex] < offset) {
            position += m_advances[glyphIndex];
            ++glyphIndex;
        }
    }
    return position;
}
Exemple #10
0
void RoundButton::Numbers::paint(Painter &p, int x, int y, int outerWidth) {
	auto digitsCount = _digits.size();
	if (!digitsCount) return;

	auto progress = anim::easeOutCirc(1., _a_ready.current(1.));
	auto width = anim::interpolate(_fromWidth, _toWidth, progress);

	QString singleChar('0');
	if (rtl()) x = outerWidth - x - width;
	x += width - _digits.size() * _digitWidth;
	auto fromTop = anim::interpolate(0, _st.font->height, progress) * (_growing ? 1 : -1);
	auto toTop = anim::interpolate(_st.font->height, 0, progress) * (_growing ? -1 : 1);
	for (auto i = 0; i != digitsCount; ++i) {
		auto &digit = _digits[i];
		auto from = digit.from;
		auto to = digit.to;
		if (from.unicode()) {
			p.setOpacity(1. - progress);
			singleChar[0] = from;
			p.drawText(x + (_digitWidth - digit.fromWidth) / 2, y + fromTop + _st.font->ascent, singleChar);
		}
		if (to.unicode()) {
			p.setOpacity(progress);
			singleChar[0] = to;
			p.drawText(x + (_digitWidth - digit.toWidth) / 2, y + toTop + _st.font->ascent, singleChar);
		}
		x += _digitWidth;
	}
	p.setOpacity(1.);
}
HarfBuzzShaper::HarfBuzzRun::HarfBuzzRun(unsigned numCharacters, TextDirection direction, hb_buffer_t* harfbuzzBuffer)
    : m_numCharacters(numCharacters)
    , m_direction(direction)
{
    m_numGlyphs = hb_buffer_get_length(harfbuzzBuffer);
    m_glyphs.resize(m_numGlyphs);
    m_advances.resize(m_numGlyphs);
    m_offsets.resize(m_numGlyphs);
    m_glyphToCharacterIndex.resize(m_numGlyphs);
    m_logClusters.resize(m_numCharacters);

    hb_glyph_info_t* infos = hb_buffer_get_glyph_infos(harfbuzzBuffer, 0);
    for (unsigned i = 0; i < m_numGlyphs; ++i)
        m_glyphToCharacterIndex[i] = infos[i].cluster;

    // Fill logical clusters
    unsigned index = 0;
    while (index < m_numGlyphs) {
        unsigned nextIndex = index + 1;
        while (nextIndex < m_numGlyphs && infos[index].cluster == infos[nextIndex].cluster)
            ++nextIndex;
        if (rtl()) {
            int nextCluster = nextIndex < m_numGlyphs ? infos[nextIndex].cluster : -1;
            for (int j = infos[index].cluster; j > nextCluster; --j)
                m_logClusters[j] = index;
        } else {
            unsigned nextCluster = nextIndex < m_numGlyphs ? infos[nextIndex].cluster : m_numCharacters;
            for (unsigned j = infos[index].cluster; j < nextCluster; ++j)
                m_logClusters[j] = index;
        }
        index = nextIndex;
    }
}
void testObj::test<4>(void)
{
  WaitingLockData    wld;
  ReadTryLock        rtl(mutexRW_);
  wld.setPtr( leaf_.shared_ptr() );
  ensure("locking for read only failed", rtl.ownsLock()==true );
  ensure("invalid pointer", wld.getWhenDifferOrLocked( leaf_.shared_ptr(), rtl)==leaf_ );
}
Exemple #13
0
void PopupMenu::keyPressEvent(QKeyEvent *e) {
    if (_childMenuIndex >= 0) {
        return _menus.at(_childMenuIndex)->keyPressEvent(e);
    }

    if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
        itemPressed(PressSourceKeyboard);
        return;
    } else if (e->key() == Qt::Key_Escape) {
        hideMenu(_parent ? true : false);
        return;
    }
    if (e->key() == (rtl() ? Qt::Key_Left : Qt::Key_Right)) {
        if (_selected >= 0 && _menus.at(_selected)) {
            itemPressed(PressSourceKeyboard);
            return;
        } else if (_selected < 0 && _parent && !_actions.isEmpty()) {
            _mouseSelection = false;
            setSelected(0);
        }
    } else if (e->key() == (rtl() ? Qt::Key_Right : Qt::Key_Left)) {
        if (_parent) {
            hideMenu(true);
        }
    }
    if ((e->key() != Qt::Key_Up && e->key() != Qt::Key_Down) || _actions.size() < 1) return;

    int32 delta = (e->key() == Qt::Key_Down ? 1 : -1), start = _selected;
    if (start < 0 || start >= _actions.size()) {
        start = (delta > 0) ? (_actions.size() - 1) : 0;
    }
    int32 newSelected = start;
    do {
        newSelected += delta;
        if (newSelected < 0) {
            newSelected += _actions.size();
        } else if (newSelected >= _actions.size()) {
            newSelected -= _actions.size();
        }
    } while (newSelected != start && (!_actions.at(newSelected)->isEnabled() || _actions.at(newSelected)->isSeparator()));

    if (_actions.at(newSelected)->isEnabled() && !_actions.at(newSelected)->isSeparator()) {
        _mouseSelection = false;
        setSelected(newSelected);
    }
}
void Inner::paintInlineItems(Painter &p, const QRect &r) {
	if (_restrictedLabel) {
		return;
	}
	if (_rows.isEmpty() && !_switchPmButton) {
		p.setFont(st::normalFont);
		p.setPen(st::noContactsColor);
		p.drawText(QRect(0, 0, width(), (height() / 3) * 2 + st::normalFont->height), lang(lng_inline_bot_no_results), style::al_center);
		return;
	}
	auto gifPaused = _controller->isGifPausedAtLeastFor(Window::GifPauseReason::InlineResults);
	InlineBots::Layout::PaintContext context(getms(), false, gifPaused, false);

	auto top = st::stickerPanPadding;
	if (_switchPmButton) {
		top += _switchPmButton->height() + st::inlineResultsSkip;
	}

	auto fromx = rtl() ? (width() - r.x() - r.width()) : r.x();
	auto tox = rtl() ? (width() - r.x()) : (r.x() + r.width());
	for (auto row = 0, rows = _rows.size(); row != rows; ++row) {
		auto &inlineRow = _rows[row];
		if (top >= r.top() + r.height()) break;
		if (top + inlineRow.height > r.top()) {
			auto left = st::inlineResultsLeft - st::buttonRadius;
			if (row == rows - 1) context.lastRow = true;
			for (int col = 0, cols = inlineRow.items.size(); col < cols; ++col) {
				if (left >= tox) break;

				auto item = inlineRow.items.at(col);
				auto w = item->width();
				if (left + w > fromx) {
					p.translate(left, top);
					item->paint(p, r.translated(-left, -top), &context);
					p.translate(-left, -top);
				}
				left += w;
				if (item->hasRightSkip()) {
					left += st::inlineResultsSkip;
				}
			}
		}
		top += inlineRow.height;
	}
}
Exemple #15
0
void StickersBox::CounterWidget::paintEvent(QPaintEvent *e) {
	Painter p(this);

	if (!_text.isEmpty()) {
		auto unreadRight = rtl() ? 0 : width();
		auto unreadTop = 0;
		Dialogs::Layout::paintUnreadCount(p, _text, unreadRight, unreadTop, _st);
	}
}
Exemple #16
0
void SplittedWidget::update(const QRegion &r) {
	if (rtl()) {
		TWidget::update(r.translated(-otherWidth(), 0).intersected(rect()));
		emit updateOther(r);
	} else {
		TWidget::update(r.intersected(rect()));
		emit updateOther(r.translated(-width(), 0));
	}
}
Exemple #17
0
void SplittedWidget::paintEvent(QPaintEvent *e) {
	Painter p(this);
	if (rtl()) {
		p.translate(-otherWidth(), 0);
		paintRegion(p, e->region().translated(otherWidth(), 0), false);
	} else {
		paintRegion(p, e->region(), false);
	}
}
int HarfBuzzShaper::HarfBuzzRun::xPositionForOffset(unsigned offset)
{
    ASSERT(offset < m_numCharacters);
    unsigned glyphIndex = m_logClusters[offset];
    ASSERT(glyphIndex < m_numGlyphs);
    float position = m_offsets[glyphIndex].x();
    if (rtl())
        position += m_advances[glyphIndex];
    return roundf(position);
}
Exemple #19
0
void SplittedWidgetOther::paintEvent(QPaintEvent *e) {
	Painter p(this);
	SplittedWidget *s = static_cast<SplittedWidget*>(static_cast<ScrollArea*>(parentWidget())->widget());
	if (rtl()) {
		s->paintRegion(p, e->region(), true);
	} else {
		p.translate(-s->width(), 0);
		s->paintRegion(p, e->region().translated(s->width(), 0), true);
	}
}
void testObj::test<3>(void)
{
  WriteLock       lock(mutexRW_);
  WaitingLockData wld;
  GraphNodePtrNN  leaf2=makeLeaf();
  wld.setPtr( leaf_.shared_ptr() );
  ReadTryLock     rtl(mutexRW_);
  ensure("locking for read only didn't failed", rtl.ownsLock()==false );
  ensure("invalid pointer", wld.getWhenDifferOrLocked( makeLeaf().shared_ptr(), rtl)==leaf_ );
}
Exemple #21
0
void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource source) {
	_parent = parent;

	auto origin = PanelAnimation::Origin::TopLeft;
	auto w = p - QPoint(0, _padding.top());
	auto r = Sandbox::screenGeometry(p);
	_useTransparency = Platform::TransparentWindowsSupported(p);
	handleCompositingUpdate();
	if (rtl()) {
		if (w.x() - width() < r.x() - _padding.left()) {
			if (_parent && w.x() + _parent->width() - _padding.left() - _padding.right() + width() - _padding.right() <= r.x() + r.width()) {
				w.setX(w.x() + _parent->width() - _padding.left() - _padding.right());
			} else {
				w.setX(r.x() - _padding.left());
			}
		} else {
			w.setX(w.x() - width());
		}
	} else {
		if (w.x() + width() - _padding.right() > r.x() + r.width()) {
			if (_parent && w.x() - _parent->width() + _padding.left() + _padding.right() - width() + _padding.right() >= r.x() - _padding.left()) {
				w.setX(w.x() + _padding.left() + _padding.right() - _parent->width() - width() + _padding.left() + _padding.right());
			} else {
				w.setX(p.x() - width() + _padding.right());
			}
			origin = PanelAnimation::Origin::TopRight;
		}
	}
	if (w.y() + height() - _padding.bottom() > r.y() + r.height()) {
		if (_parent) {
			w.setY(r.y() + r.height() - height() + _padding.bottom());
		} else {
			w.setY(p.y() - height() + _padding.bottom());
			origin = (origin == PanelAnimation::Origin::TopRight) ? PanelAnimation::Origin::BottomRight : PanelAnimation::Origin::BottomLeft;
		}
	}
	if (w.x() < r.x()) {
		w.setX(r.x());
	}
	if (w.y() < r.y()) {
		w.setY(r.y());
	}
	move(w);

	setOrigin(origin);
	_menu->setShowSource(source);

	startShowAnimation();

	psUpdateOverlayed(this);
	show();
	psShowOverAll(this);
	windowHandle()->requestActivate();
	activateWindow();
}
Exemple #22
0
void PopupTooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *st) {
	if (!_hideByLeaveTimer.isSingleShot()) {
		_hideByLeaveTimer.setSingleShot(true);
		connect(&_hideByLeaveTimer, SIGNAL(timeout()), this, SLOT(onHideByLeave()));

		Sandbox::installEventFilter(this);
	}

	_point = m;
	_st = st;
	_text = Text(_st->textFont, text, _textPlainOptions, _st->widthMax, true);

	int32 addw = 2 * st::lineWidth + _st->textPadding.left() + _st->textPadding.right();
	int32 addh = 2 * st::lineWidth + _st->textPadding.top() + _st->textPadding.bottom();

	// count tooltip size
	QSize s(addw + _text.maxWidth(), addh + _text.minHeight());
	if (s.width() > _st->widthMax) {
		s.setWidth(addw + _text.countWidth(_st->widthMax - addw));
		s.setHeight(addh + _text.countHeight(s.width() - addw));
	}
	int32 maxh = addh + (_st->linesMax * _st->textFont->height);
	if (s.height() > maxh) {
		s.setHeight(maxh);
	}

	// count tooltip position
	QPoint p(m + _st->shift);
	if (rtl()) {
		p.setX(m.x() - s.width() - _st->shift.x());
	}
	if (s.width() < 2 * _st->shift.x()) {
		p.setX(m.x() - (s.width() / 2));
	}

	// adjust tooltip position
	QRect r(QApplication::desktop()->screenGeometry(m));
	if (r.x() + r.width() - _st->skip < p.x() + s.width() && p.x() + s.width() > m.x()) {
		p.setX(qMax(r.x() + r.width() - int32(_st->skip) - s.width(), m.x() - s.width()));
	}
	if (r.x() + _st->skip > p.x() && p.x() < m.x()) {
		p.setX(qMin(m.x(), r.x() + int32(_st->skip)));
	}
	if (r.y() + r.height() - _st->skip < p.y() + s.height()) {
		p.setY(m.y() - s.height() - _st->skip);
	}
	if (r.y() > p.x()) {
		p.setY(qMin(m.y() + _st->shift.y(), r.y() + r.height() - s.height()));
	}

	setGeometry(QRect(p, s));

	_hideByLeaveTimer.stop();
	show();
}
Exemple #23
0
void PopupMenu::popupChildMenu(PressSource source) {
    if (_childMenuIndex >= 0) {
        _menus.at(_childMenuIndex)->hideMenu(true);
        _childMenuIndex = -1;
    }
    if (_selected >= 0 && _selected < _menus.size() && _menus.at(_selected)) {
        QPoint p(_inner.x() + (rtl() ? _padding.right() : _inner.width() - _padding.left()), _inner.y() + _st.skip + itemY(_selected));
        _childMenuIndex = _selected;
        _menus.at(_childMenuIndex)->showMenu(geometry().topLeft() + p, this, source);
    }
}
RadialState RadialAnimation::computeState() {
	auto length = MinArcLength + qRound(a_arcEnd.current());
	auto from = QuarterArcLength
		- length
		- (anim::Disabled() ? 0 : qRound(a_arcStart.current()));
	if (rtl()) {
		from = QuarterArcLength - (from - QuarterArcLength) - length;
		if (from < 0) from += FullArcLength;
	}
	return { _opacity, from, length };
}
void MonoIcon::paint(QPainter &p, const QPoint &pos, int outerw) const {
	int w = width(), h = height();
	QPoint fullOffset = pos + offset();
	int partPosX = rtl() ? (outerw - fullOffset.x() - w) : fullOffset.x();
	int partPosY = fullOffset.y();

	ensureLoaded();
	if (_pixmap.isNull()) {
		p.fillRect(partPosX, partPosY, w, h, _color);
	} else {
		p.drawPixmap(partPosX, partPosY, _pixmap);
	}
}
void RippleAnimation::paint(QPainter &p, int x, int y, int outerWidth, const QColor *colorOverride) {
	if (_ripples.empty()) {
		return;
	}

	if (rtl()) x = outerWidth - x - (_mask.width() / cIntRetinaFactor());
	p.translate(x, y);
	for (const auto &ripple : _ripples) {
		ripple->paint(p, _mask, colorOverride);
	}
	p.translate(-x, -y);
	clearFinished();
}
Exemple #27
0
FloatRect ComplexTextController::selectionRect(const FloatPoint& point, int height, int from, int to)
{
    int fromX = -1, toX = -1;
    // Iterate through the script runs in logical order, searching for the run covering the positions of interest.
    while (nextScriptRun() && (fromX == -1 || toX == -1)) {
        if (fromX == -1 && from >= 0 && static_cast<unsigned>(from) < numCodePoints()) {
            // |from| is within this script run. So we index the clusters log to
            // find which glyph this code-point contributed to and find its x
            // position.
            int glyph = m_item.log_clusters[from];
            fromX = positions()[glyph].x();
            if (rtl())
                fromX += truncateFixedPointToInteger(m_item.advances[glyph]);
        } else
            from -= numCodePoints();

        if (toX == -1 && to >= 0 && static_cast<unsigned>(to) < numCodePoints()) {
            int glyph = m_item.log_clusters[to];
            toX = positions()[glyph].x();
            if (rtl())
                toX += truncateFixedPointToInteger(m_item.advances[glyph]);
        } else
            to -= numCodePoints();
    }

    // The position in question might be just after the text.
    if (fromX == -1)
        fromX = offsetX();
    if (toX == -1)
        toX = offsetX();

    ASSERT(fromX != -1 && toX != -1);

    if (fromX < toX)
        return FloatRect(point.x() + fromX, point.y(), toX - fromX, height);

    return FloatRect(point.x() + toX, point.y(), fromX - toX, height);
}
Exemple #28
0
void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, PressSource source) {
    _parent = parent;

    QPoint w = p - QPoint(0, _padding.top());
    QRect r = App::app() ? App::app()->desktop()->screenGeometry(p) : QDesktopWidget().screenGeometry(p);
    if (rtl()) {
        if (w.x() - width() < r.x() - _padding.left()) {
            if (_parent && w.x() + _parent->width() - _padding.left() - _padding.right() + width() - _padding.right() <= r.x() + r.width()) {
                w.setX(w.x() + _parent->width() - _padding.left() - _padding.right());
            } else {
                w.setX(r.x() - _padding.left());
            }
        } else {
            w.setX(w.x() - width());
        }
    } else {
        if (w.x() + width() - _padding.right() > r.x() + r.width()) {
            if (_parent && w.x() - _parent->width() + _padding.left() + _padding.right() - width() + _padding.right() >= r.x() - _padding.left()) {
                w.setX(w.x() + _padding.left() + _padding.right() - _parent->width() - width() + _padding.left() + _padding.right());
            } else {
                w.setX(r.x() + r.width() - width() + _padding.right());
            }
        }
    }
    if (w.y() + height() - _padding.bottom() > r.y() + r.height()) {
        if (_parent) {
            w.setY(r.y() + r.height() - height() + _padding.bottom());
        } else {
            w.setY(p.y() - height() + _padding.bottom());
        }
    }
    if (w.y() < r.y()) {
        w.setY(r.y());
    }
    move(w);

    _mouseSelection = (source == PressSourceMouse);
    setSelected((source == PressSourceMouse || _actions.isEmpty()) ? -1 : 0);
    psUpdateOverlayed(this);
    show();
    psShowOverAll(this);
    windowHandle()->requestActivate();
    activateWindow();

    if (_a_hide.animating()) {
        _a_hide.stop();
        _cache = QPixmap();
    }
    a_opacity = anim::fvalue(1, 1);
}
Exemple #29
0
void ScrollArea::resizeEvent(QResizeEvent *e) {
	QScrollArea::resizeEvent(e);
	hor.recountSize();
	vert.recountSize();
	topSh.setGeometry(QRect(0, 0, width(), qAbs(_st.topsh)));
	bottomSh.setGeometry(QRect(0, height() - qAbs(_st.bottomsh), width(), qAbs(_st.bottomsh)));
	if (SplittedWidget *w = qobject_cast<SplittedWidget*>(widget())) {
		w->resize(width() - w->otherWidth(), w->height());
		if (!rtl()) {
			_other->move(w->width(), w->y());
		}
	}
	emit geometryChanged();
}
static void createAndAppendTextDirectionSubMenu(const HitTestResult& result, ContextMenuItem& textDirectionMenuItem)
{
    ContextMenu textDirectionMenu(result);

    ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefault, contextMenuItemTagDefaultDirection());
    ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeftToRight, contextMenuItemTagLeftToRight());
    ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRightToLeft, contextMenuItemTagRightToLeft());

    textDirectionMenu.appendItem(defaultItem);
    textDirectionMenu.appendItem(ltr);
    textDirectionMenu.appendItem(rtl);

    textDirectionMenuItem.setSubMenu(&textDirectionMenu);
}