Exemple #1
0
void Widget::onParentResized() {
    int width = st::toastMaxWidth;
    accumulate_min(width, st::toastPadding.left() + _text.maxWidth() + st::toastPadding.right());
    accumulate_min(width, parentWidget()->width() - 2 * int(st::toastMinMargin));
    int height = st::toastPadding.top() + _text.minHeight() + st::toastPadding.bottom();
    setGeometry((parentWidget()->width() - width) / 2, (parentWidget()->height() - height) / 2, width, height);
}
int InfoWidget::resizeGetHeight(int newWidth) {
	int initialHeight = contentTop();
	int newHeight = initialHeight;

	int marginLeft = st::profileBlockTextPart.margin.left();
	int marginRight = st::profileBlockTextPart.margin.right();
	int left = st::profileBlockTitlePosition.x();
	if (_about) {
		int textWidth = _about->naturalWidth();
		int availableWidth = newWidth - left - st::profileBlockMarginRight;
		int maxWidth = st::msgMaxWidth;
		accumulate_min(textWidth, availableWidth);
		accumulate_min(textWidth, st::msgMaxWidth);
		_about->resizeToWidth(textWidth + marginLeft + marginRight);
		_about->moveToLeft(left - marginLeft, newHeight - st::profileBlockTextPart.margin.top());
		newHeight += _about->height();
	}

	auto moveLabeledText = [&newHeight, left, newWidth, marginLeft, marginRight](Ui::FlatLabel *label, Ui::FlatLabel *text, Ui::FlatLabel *shortText) {
		if (!label) return;

		label->moveToLeft(left, newHeight);
		int textLeft = left + label->width() + st::normalFont->spacew;
		int textWidth = text->naturalWidth();
		int availableWidth = newWidth - textLeft - st::profileBlockMarginRight;
		bool doesNotFit = (textWidth > availableWidth);
		accumulate_min(textWidth, availableWidth);
		accumulate_min(textWidth, st::msgMaxWidth);
		text->resizeToWidth(textWidth + marginLeft + marginRight);
		text->moveToLeft(textLeft - marginLeft, newHeight - st::profileBlockOneLineTextPart.margin.top());
		if (shortText) {
			shortText->resizeToWidth(textWidth + marginLeft + marginRight);
			shortText->moveToLeft(textLeft - marginLeft, newHeight - st::profileBlockOneLineTextPart.margin.top());
			if (doesNotFit) {
				shortText->show();
				text->hide();
			} else {
				shortText->hide();
				text->show();
			}
		}
		newHeight += label->height() + st::profileBlockOneLineSkip;
	};
	moveLabeledText(_channelLinkLabel, _channelLink, _channelLinkShort);
	moveLabeledText(_mobileNumberLabel, _mobileNumber, nullptr);
	moveLabeledText(_usernameLabel, _username, nullptr);

	newHeight += st::profileBlockMarginBottom;
	return newHeight;
}
void ActionsWidget::resizeButton(Ui::LeftOutlineButton *button, int newWidth, int top) {
	int left = defaultOutlineButtonLeft();
	int availableWidth = newWidth - left - st::profileBlockMarginRight;
	accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
	button->resizeToWidth(availableWidth);
	button->moveToLeft(left, top);
}
float64 Float::outRatio() const {
	auto parent = parentWidget()->rect();
	auto min = 1.;
	if (x() < parent.x()) {
		accumulate_min(min, 1. - (parent.x() - x()) / float64(width()));
	}
	if (y() < parent.y()) {
		accumulate_min(min, 1. - (parent.y() - y()) / float64(height()));
	}
	if (x() + width() > parent.x() + parent.width()) {
		accumulate_min(min, 1. - (x() + width() - parent.x() - parent.width()) / float64(width()));
	}
	if (y() + height() > parent.y() + parent.height()) {
		accumulate_min(min, 1. - (y() + height() - parent.y() - parent.height()) / float64(height()));
	}
	return snap(min, 0., 1.);
}
int InviteLinkWidget::resizeGetHeight(int newWidth) {
	int newHeight = contentTop();

	int marginLeft = st::profileBlockTextPart.margin.left();
	int marginRight = st::profileBlockTextPart.margin.right();
	int left = st::profileBlockTitlePosition.x();
	if (_link) {
		int textWidth = _link->naturalWidth();
		int availableWidth = newWidth - left - st::profileBlockMarginRight;
		int maxWidth = st::msgMaxWidth;
		accumulate_min(textWidth, availableWidth);
		accumulate_min(textWidth, st::msgMaxWidth);
		_link->resizeToWidth(textWidth + marginLeft + marginRight);
		_link->moveToLeft(left - marginLeft, newHeight - st::profileBlockTextPart.margin.top());
		newHeight += _link->height();
	}

	newHeight += st::profileBlockMarginBottom;
	return newHeight;
}
int InfoWidget::LabeledWidget::resizeGetHeight(int newWidth) {
	if (!_label) return 0;

	_label->moveToLeft(
		0,
		st::settingsBlockOneLineTextPart.margin.top(),
		newWidth);
	_label->resizeToNaturalWidth(newWidth);

	int textLeft = _label->width() + st::normalFont->spacew;
	int textWidth = _text->naturalWidth();
	int availableWidth = newWidth - textLeft;
	bool doesNotFit = (textWidth > availableWidth);
	accumulate_min(textWidth, availableWidth);
	accumulate_min(textWidth, st::msgMaxWidth);
	if (textWidth < 0) {
		textWidth = 0;
	}
	_text->resizeToWidth(textWidth);
	_text->moveToLeft(
		textLeft,
		st::settingsBlockOneLineTextPart.margin.top(),
		newWidth);
	if (_shortText) {
		_shortText->resizeToWidth(textWidth);
		_shortText->moveToLeft(
			textLeft,
			st::settingsBlockOneLineTextPart.margin.top(),
			newWidth);
		if (doesNotFit) {
			_shortText->show();
			_text->hide();
		} else {
			_shortText->hide();
			_text->show();
		}
	}
	return st::settingsBlockOneLineTextPart.margin.top()
		+ qMax(_label->heightNoMargins(), _text->heightNoMargins())
		+ st::settingsBlockOneLineTextPart.margin.bottom();
}
Exemple #7
0
void InnerDropdown::updateHeight() {
	int newHeight = _st.padding.top() + _st.scrollMargin.top() + _st.scrollMargin.bottom() + _st.padding.bottom();
	if (auto widget = static_cast<ScrolledWidget*>(_scroll->widget())) {
		newHeight += widget->height();
	}
	if (_maxHeight > 0) {
		accumulate_min(newHeight, _maxHeight);
	}
	if (newHeight != height()) {
		resize(width(), newHeight);
	}
}
int InnerDropdown::resizeGetHeight(int newWidth) {
	auto newHeight = _st.padding.top() + _st.scrollMargin.top() + _st.scrollMargin.bottom() + _st.padding.bottom();
	if (auto widget = static_cast<TWidget*>(_scroll->widget())) {
		auto containerWidth = newWidth - _st.padding.left() - _st.padding.right() - _st.scrollMargin.left() - _st.scrollMargin.right();
		widget->resizeToWidth(containerWidth);
		newHeight += widget->height();
	}
	if (_maxHeight > 0) {
		accumulate_min(newHeight, _maxHeight);
	}
	return newHeight;
}
Exemple #9
0
QRect MultiSelect::Inner::Item::paintArea(int outerWidth) const {
	if (_copies.empty()) {
		return rect();
	}
	auto yMin = 0, yMax = 0;
	for_const (auto &copy, _copies) {
		accumulate_max(yMax, copy.y);
		if (yMin) {
			accumulate_min(yMin, copy.y);
		} else {
			yMin = copy.y;
		}
	}
void SharedMediaWidget::resizeButtons(int newWidth, int *top) {
	t_assert(top != nullptr);

	int left = defaultOutlineButtonLeft();
	int availableWidth = newWidth - left - st::profileBlockMarginRight;
	accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
	for_const (auto button, _mediaButtons) {
		if (!button) continue;

		button->resizeToWidth(availableWidth);
		button->moveToLeft(left, *top);
		*top += button->height();
	}
}
QSize HistoryGroupedMedia::countCurrentSize(int newWidth) {
	accumulate_min(newWidth, maxWidth());
	auto newHeight = 0;
	if (newWidth < st::historyGroupWidthMin) {
		return { newWidth, newHeight };
	}

	const auto initialSpacing = st::historyGroupSkip;
	const auto factor = newWidth / float64(maxWidth());
	const auto scale = [&](int value) {
		return int(std::round(value * factor));
	};
	const auto spacing = scale(initialSpacing);
	for (auto &part : _parts) {
		const auto sides = part.sides;
		const auto initialGeometry = part.initialGeometry;
		const auto needRightSkip = !(sides & RectPart::Right);
		const auto needBottomSkip = !(sides & RectPart::Bottom);
		const auto initialLeft = initialGeometry.x();
		const auto initialTop = initialGeometry.y();
		const auto initialRight = initialLeft
			+ initialGeometry.width()
			+ (needRightSkip ? initialSpacing : 0);
		const auto initialBottom = initialTop
			+ initialGeometry.height()
			+ (needBottomSkip ? initialSpacing : 0);
		const auto left = scale(initialLeft);
		const auto top = scale(initialTop);
		const auto width = scale(initialRight)
			- left
			- (needRightSkip ? spacing : 0);
		const auto height = scale(initialBottom)
			- top
			- (needBottomSkip ? spacing : 0);
		part.geometry = QRect(left, top, width, height);

		accumulate_max(newHeight, top + height);
	}

	if (!_caption.isEmpty()) {
		const auto captionw = newWidth - st::msgPadding.left() - st::msgPadding.right();
		newHeight += st::mediaCaptionSkip + _caption.countHeight(captionw);
		if (isBubbleBottom()) {
			newHeight += st::msgPadding.bottom();
		}
	}

	return { newWidth, newHeight };
}
Controller::ColumnLayout Controller::computeColumnLayout() const {
	auto layout = Adaptive::WindowLayout::OneColumn;

	auto bodyWidth = window()->bodyWidget()->width();
	auto dialogsWidth = 0, chatWidth = 0, thirdWidth = 0;

	auto useOneColumnLayout = [&] {
		auto minimalNormal = st::columnMinimalWidthLeft
			+ st::columnMinimalWidthMain;
		if (bodyWidth < minimalNormal) {
			return true;
		}
		return false;
	};

	auto useNormalLayout = [&] {
		// Used if useSmallColumnLayout() == false.
		if (bodyWidth < minimalThreeColumnWidth()) {
			return true;
		}
		if (!session().settings().tabbedSelectorSectionEnabled()
			&& !session().settings().thirdSectionInfoEnabled()) {
			return true;
		}
		return false;
	};

	if (useOneColumnLayout()) {
		dialogsWidth = chatWidth = bodyWidth;
	} else if (useNormalLayout()) {
		layout = Adaptive::WindowLayout::Normal;
		dialogsWidth = countDialogsWidthFromRatio(bodyWidth);
		accumulate_min(dialogsWidth, bodyWidth - st::columnMinimalWidthMain);
		chatWidth = bodyWidth - dialogsWidth;
	} else {
		layout = Adaptive::WindowLayout::ThreeColumn;
		dialogsWidth = countDialogsWidthFromRatio(bodyWidth);
		thirdWidth = countThirdColumnWidthFromRatio(bodyWidth);
		auto shrink = shrinkDialogsAndThirdColumns(
			dialogsWidth,
			thirdWidth,
			bodyWidth);
		dialogsWidth = shrink.dialogsWidth;
		thirdWidth = shrink.thirdWidth;

		chatWidth = bodyWidth - dialogsWidth - thirdWidth;
	}
	return { bodyWidth, dialogsWidth, chatWidth, thirdWidth, layout };
}
Exemple #13
0
void InnerDropdown::resizeToContent() {
	auto newWidth = _st.padding.left() + _st.scrollMargin.left() + _st.scrollMargin.right() + _st.padding.right();
	auto newHeight = _st.padding.top() + _st.scrollMargin.top() + _st.scrollMargin.bottom() + _st.padding.bottom();
	if (auto widget = static_cast<Container*>(_scroll->widget())) {
		widget->resizeToContent();
		newWidth += widget->width();
		newHeight += widget->height();
	}
	if (_maxHeight > 0) {
		accumulate_min(newHeight, _maxHeight);
	}
	if (newWidth != width() || newHeight != height()) {
		resize(newWidth, newHeight);
	}
}
QSize HistoryGame::countCurrentSize(int newWidth) {
	accumulate_min(newWidth, maxWidth());
	auto innerWidth = newWidth - st::msgPadding.left() - st::webPageLeft - st::msgPadding.right();

	// enable any count of lines in game description / message
	auto linesMax = 4096;
	auto lineHeight = unitedLineHeight();
	auto newHeight = 0;
	if (_title.isEmpty()) {
		_titleLines = 0;
	} else {
		if (_title.countHeight(innerWidth) < 2 * st::webPageTitleFont->height) {
			_titleLines = 1;
		} else {
			_titleLines = 2;
		}
		newHeight += _titleLines * lineHeight;
	}

	if (_description.isEmpty()) {
		_descriptionLines = 0;
	} else {
		auto descriptionHeight = _description.countHeight(innerWidth);
		if (descriptionHeight < (linesMax - _titleLines) * st::webPageDescriptionFont->height) {
			_descriptionLines = (descriptionHeight / st::webPageDescriptionFont->height);
		} else {
			_descriptionLines = (linesMax - _titleLines);
		}
		newHeight += _descriptionLines * lineHeight;
	}

	if (_attach) {
		auto attachAtTop = !_titleLines && !_descriptionLines;
		if (!attachAtTop) newHeight += st::mediaInBubbleSkip;

		QMargins bubble(_attach->bubbleMargins());

		_attach->resizeGetHeight(innerWidth + bubble.left() + bubble.right());
		newHeight += _attach->height() - bubble.top() - bubble.bottom();
		if (isBubbleBottom() && _attach->customInfoLayout() && _attach->width() + _parent->skipBlockWidth() > innerWidth + bubble.left() + bubble.right()) {
			newHeight += bottomInfoPadding();
		}
	}
	auto padding = inBubblePadding();
	newHeight += padding.top() + padding.bottom();

	return { newWidth, newHeight };
}
Exemple #15
0
int MainWindow::tryToExtendWidthBy(int addToWidth) {
	auto desktop = QDesktopWidget().availableGeometry(this);
	auto inner = geometry();
	accumulate_min(
		addToWidth,
		std::max(desktop.width() - inner.width(), 0));
	auto newWidth = inner.width() + addToWidth;
	auto newLeft = std::min(
		inner.x(),
		desktop.x() + desktop.width() - newWidth);
	if (inner.x() != newLeft || inner.width() != newWidth) {
		setGeometry(newLeft, inner.y(), newWidth, inner.height());
	} else {
		updateControlsGeometry();
	}
	return addToWidth;
}
QSize HistoryInvoice::countCurrentSize(int newWidth) {
	accumulate_min(newWidth, maxWidth());
	auto innerWidth = newWidth - st::msgPadding.left() - st::msgPadding.right();

	auto lineHeight = unitedLineHeight();

	auto newHeight = 0;
	if (_title.isEmpty()) {
		_titleHeight = 0;
	} else {
		if (_title.countHeight(innerWidth) < 2 * st::webPageTitleFont->height) {
			_titleHeight = lineHeight;
		} else {
			_titleHeight = 2 * lineHeight;
		}
		newHeight += _titleHeight;
	}

	if (_description.isEmpty()) {
		_descriptionHeight = 0;
	} else {
		_descriptionHeight = _description.countHeight(innerWidth);
		newHeight += _descriptionHeight;
	}

	if (_attach) {
		auto attachAtTop = !_title.isEmpty() && _description.isEmpty();
		if (!attachAtTop) newHeight += st::mediaInBubbleSkip;

		QMargins bubble(_attach->bubbleMargins());

		_attach->resizeGetHeight(innerWidth + bubble.left() + bubble.right());
		newHeight += _attach->height() - bubble.top() - bubble.bottom();
		if (isBubbleBottom() && _attach->customInfoLayout() && _attach->width() + _parent->skipBlockWidth() > innerWidth + bubble.left() + bubble.right()) {
			newHeight += bottomInfoPadding();
		}
	} else {
		newHeight += st::mediaInBubbleSkip + _status.countHeight(innerWidth);
	}
	auto padding = inBubblePadding();
	newHeight += padding.top() + padding.bottom();

	return { newWidth, newHeight };
}
Exemple #17
0
void CodeInput::correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) {
	QString newText;
	int oldPos(nowCursor), newPos(-1), oldLen(now.length()), digitCount = 0;
	for (int i = 0; i < oldLen; ++i) {
		if (now[i].isDigit()) {
			++digitCount;
		}
	}
	accumulate_min(digitCount, _digitsCountMax);
	auto strict = (digitCount == _digitsCountMax);

	newText.reserve(oldLen);
	for (int i = 0; i < oldLen; ++i) {
		QChar ch(now[i]);
		if (ch.isDigit()) {
			if (!digitCount--) {
				break;
			}
			newText += ch;
			if (strict && !digitCount) {
				break;
			}
		} else if (ch == '-') {
			newText += ch;
		}
		if (i == oldPos) {
			newPos = newText.length();
		}
	}
	if (newPos < 0 || newPos > newText.size()) {
		newPos = newText.size();
	}
	if (newText != now) {
		now = newText;
		setText(now);
		startPlaceholderAnimation();
	}
	if (newPos != nowCursor) {
		nowCursor = newPos;
		setCursorPosition(nowCursor);
	}
}
int ChannelMembersWidget::resizeGetHeight(int newWidth) {
	int newHeight = contentTop();

	auto resizeButton = [this, &newHeight, newWidth](object_ptr<Ui::LeftOutlineButton> &button) {
		if (!button) {
			return;
		}

		int left = defaultOutlineButtonLeft();
		int availableWidth = newWidth - left - st::profileBlockMarginRight;
		accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
		button->resizeToWidth(availableWidth);
		button->moveToLeft(left, newHeight);
		newHeight += button->height();
	};

	resizeButton(_admins);
	resizeButton(_members);

	return newHeight;
}
TimeMs CachedUserpics::clear(TimeMs ms) {
	TimeMs result = 0;
	for (auto i = _images.begin(); i != _images.end();) {
		if (!i->until) {
			++i;
			continue;
		}
		if (i->until <= ms) {
			QFile(i->path).remove();
			i = _images.erase(i);
		} else {
			if (!result) {
				result = i->until;
			} else {
				accumulate_min(result, i->until);
			}
			++i;
		}
	}
	return result;
}
int SettingsWidget::resizeGetHeight(int newWidth) {
	int newHeight = contentTop() + st::profileEnableNotificationsTop;

	_enableNotifications->moveToLeft(st::profileBlockTitlePosition.x(), newHeight);
	newHeight += _enableNotifications->height() + st::profileSettingsBlockSkip;

	auto moveLink = [&newHeight, newWidth](Ui::LeftOutlineButton *button) {
		if (!button) return;

		int left = defaultOutlineButtonLeft();
		int availableWidth = newWidth - left - st::profileBlockMarginRight;
		accumulate_min(availableWidth, st::profileBlockOneLineWidthMax);
		button->resizeToWidth(availableWidth);
		button->moveToLeft(left, newHeight);
		newHeight += button->height();
	};
	moveLink(_manageAdmins);
	moveLink(_inviteLink);

	newHeight += st::profileBlockMarginBottom;
	return newHeight;
}
int Controller::countThirdColumnWidthFromRatio(int bodyWidth) const {
	auto result = session().settings().thirdColumnWidth();
	accumulate_max(result, st::columnMinimalWidthThird);
	accumulate_min(result, st::columnMaximalWidthThird);
	return result;
}
SearchResult ParseSearchResult(
		not_null<PeerData*> peer,
		Storage::SharedMediaType type,
		MsgId messageId,
		SparseIdsLoadDirection direction,
		const MTPmessages_Messages &data) {
	auto result = SearchResult();
	result.noSkipRange = MsgRange{ messageId, messageId };

	auto messages = [&] {
		switch (data.type()) {
		case mtpc_messages_messages: {
			auto &d = data.c_messages_messages();
			App::feedUsers(d.vusers);
			App::feedChats(d.vchats);
			result.fullCount = d.vmessages.v.size();
			return &d.vmessages.v;
		} break;

		case mtpc_messages_messagesSlice: {
			auto &d = data.c_messages_messagesSlice();
			App::feedUsers(d.vusers);
			App::feedChats(d.vchats);
			result.fullCount = d.vcount.v;
			return &d.vmessages.v;
		} break;

		case mtpc_messages_channelMessages: {
			auto &d = data.c_messages_channelMessages();
			if (auto channel = peer->asChannel()) {
				channel->ptsReceived(d.vpts.v);
			} else {
				LOG(("API Error: received messages.channelMessages when "
					"no channel was passed! (ParseSearchResult)"));
			}
			App::feedUsers(d.vusers);
			App::feedChats(d.vchats);
			result.fullCount = d.vcount.v;
			return &d.vmessages.v;
		} break;

		case mtpc_messages_messagesNotModified: {
			LOG(("API Error: received messages.messagesNotModified! "
				"(ParseSearchResult)"));
			return (const QVector<MTPMessage>*)nullptr;
		} break;
		}
		Unexpected("messages.Messages type in ParseSearchResult()");
	}();

	if (!messages) {
		return result;
	}

	auto addType = NewMessageExisting;
	result.messageIds.reserve(messages->size());
	for (auto &message : *messages) {
		if (auto item = App::histories().addNewMessage(message, addType)) {
			auto itemId = item->id;
			if ((type == Storage::SharedMediaType::kCount)
				|| item->sharedMediaTypes().test(type)) {
				result.messageIds.push_back(itemId);
			}
			accumulate_min(result.noSkipRange.from, itemId);
			accumulate_max(result.noSkipRange.till, itemId);
		}
	}
	if (messageId && result.messageIds.empty()) {
		result.noSkipRange = [&]() -> MsgRange {
			switch (direction) {
			case SparseIdsLoadDirection::Before: // All old loaded.
				return { 0, result.noSkipRange.till };
			case SparseIdsLoadDirection::Around: // All loaded.
				return { 0, ServerMaxMsgId };
			case SparseIdsLoadDirection::After: // All new loaded.
				return { result.noSkipRange.from, ServerMaxMsgId };
			}
			Unexpected("Direction in ParseSearchResult");
		}();
	}
	return result;
}