예제 #1
0
QSize HistoryVideo::countCurrentSize(int newWidth) {
	int tw = ConvertScale(_data->thumb->width()), th = ConvertScale(_data->thumb->height());
	if (!tw || !th) {
		tw = th = 1;
	}
	if (tw * st::msgVideoSize.height() > th * st::msgVideoSize.width()) {
		th = qRound((st::msgVideoSize.width() / float64(tw)) * th);
		tw = st::msgVideoSize.width();
	} else {
		tw = qRound((st::msgVideoSize.height() / float64(th)) * tw);
		th = st::msgVideoSize.height();
	}

	if (newWidth < tw) {
		th = qRound((newWidth / float64(tw)) * th);
		tw = newWidth;
	}

	_thumbw = qMax(tw, 1);
	_thumbh = qMax(th, 1);
	auto minWidth = qMax(st::minPhotoSize, _parent->infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()));
	minWidth = qMax(minWidth, documentMaxStatusWidth(_data) + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()));
	newWidth = qMax(_thumbw, minWidth);
	auto newHeight = qMax(th, st::minPhotoSize);
	if (_parent->hasBubble() && !_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 };
}
예제 #2
0
float64 ContinuousSlider::computeValue(const QPoint &pos) const {
	auto seekRect = myrtlrect(getSeekRect());
	auto result = isHorizontal() ?
		(pos.x() - seekRect.x()) / float64(seekRect.width()) :
		(1. - (pos.y() - seekRect.y()) / float64(seekRect.height()));
	return snap(result, 0., 1.);
}
예제 #3
0
void Element::paintHighlight(
		Painter &p,
		int geometryHeight) const {
	const auto animms = delegate()->elementHighlightTime(this);
	if (!animms
		|| animms >= st::activeFadeInDuration + st::activeFadeOutDuration) {
		return;
	}

	const auto top = marginTop();
	const auto bottom = marginBottom();
	const auto fill = qMin(top, bottom);
	const auto skiptop = top - fill;
	const auto fillheight = fill + geometryHeight + fill;

	const auto dt = (animms > st::activeFadeInDuration)
		? (1. - (animms - st::activeFadeInDuration)
			/ float64(st::activeFadeOutDuration))
		: (animms / float64(st::activeFadeInDuration));
	const auto o = p.opacity();
	p.setOpacity(o * dt);
	p.fillRect(
		0,
		skiptop,
		width(),
		fillheight,
		st::defaultTextPalette.selectOverlay);
	p.setOpacity(o);
}
예제 #4
0
CGOGN_IO_API std::string  vtk_data_type_to_cgogn_name_of_type(const std::string& vtk_type_str)
{
	const std::string& data_type = to_lower(vtk_type_str);
	static const std::map<std::string, std::string> type_map{
		{"char", name_of_type(int8())},
		{"int8", name_of_type(int8())},
		{"unsigned_char", name_of_type(uint8())},
		{"uint8", name_of_type(uint8())},
		{"short", name_of_type(int16())},
		{"int16", name_of_type(int16())},
		{"unsigned_short", name_of_type(uint16())},
		{"uint16", name_of_type(uint16())},
		{"int", name_of_type(int32())},
		{"int32", name_of_type(int32())},
		{"unsigned_int", name_of_type(uint32())},
		{"uint32", name_of_type(uint32())},
		{"long", name_of_type(int64())},
		{"int64", name_of_type(int64())},
		{"unsigned_long", name_of_type(uint64())},
		{"uint64", name_of_type(uint64())},
		{"float", name_of_type(float32())},
		{"float32", name_of_type(float32())},
		{"double", name_of_type(float64())},
		{"float64", name_of_type(float64())}
	};

	const auto it = type_map.find(data_type);
	if ( it != type_map.end())
		return it->second;
	cgogn_log_error("vtk_data_type_to_cgogn_name_of_type") << "Unknown vtk type \"" << vtk_type_str << "\".";
	return std::string();
}
GfxUtility::IntersectionResult 
GfxUtility::getIntersection(const MC2Point& p1, const MC2Point& p2,
                            const MC2Point& p3, const MC2Point& p4,
                            MC2Point& intersection)
{
   int32 x1 = p1.getX();
   int32 y1 = p1.getY();
   int32 x2 = p2.getX();
   int32 y2 = p2.getY();
   int32 v1 = p3.getX();
   int32 w1 = p3.getY();
   int32 v2 = p4.getX();
   int32 w2 = p4.getY();
   
   // Can handle vertical lines.

   // x = x1 + t*alpha
   // y = y1 + t*beta
   //
   // v = v1 + s*gamma
   // w = w1 + s*theta
   //
   // alpha, beta, gamma, theta as stated below


   int32 alpha    = x2 - x1;
   int32 beta     = y2 - y1;
   int32 gamma    = v2 - v1;
   int32 theta    = w2 - w1;

   int64 denominator = int64(theta)*alpha - int64(gamma)*beta;

   // Check if the lines are parallell
   if (denominator == 0) {
      return LINE_PARALLEL;
   }

   // Solve the equation system
   float64 s = float64(int64(y1 - w1)*alpha + int64(v1 - x1)*beta) /
               denominator;

   float64 t = float64( int64(v1 - x1)*theta + int64(y1 - w1)*gamma ) /
               denominator;


   if ( ( s < 0.0 ) || ( s > 1.0 ) ) {
      mc2dbg8 << "[GU]: s out of range - no intersect" << endl;
      return LINE_NON_INTERSECTING;
   }
   if ( ( t < 0.0 ) || ( t > 1.0 ) ) {
      mc2dbg8 << "[GU]: percentFromx1y1 out of range - no intersect" << endl;
      return LINE_NON_INTERSECTING;
   }

   intersection.getX() = int32(v1 + rint(s*gamma));
   intersection.getY() = int32(w1 + rint(s*theta));

   return LINE_INTERSECTING;

}
float64 ContinuousSlider::computeValue(const QPoint &pos) const {
	const auto seekRect = myrtlrect(getSeekRect());
	const auto result = isHorizontal() ?
		(pos.x() - seekRect.x()) / float64(seekRect.width()) :
		(1. - (pos.y() - seekRect.y()) / float64(seekRect.height()));
	const auto snapped = snap(result, 0., 1.);
	return _adjustCallback ? _adjustCallback(snapped) : snapped;
}
bool
MC2BoundingBox::getCenter( int32& lat, int32& lon ) const
{
   if (!isValid()) 
      return (false);
   lon = minLon + int32(rint(float64((maxLon - minLon)) / 2));
   lat = minLat + int32(rint(float64((maxLat - minLat)) / 2));
   return (true);
}
예제 #8
0
void Switcher::paintEvent(QPaintEvent *e) {
	QPainter p(this);

	p.fillRect(rect(), _st.bgColor->b);
	if (!_buttons.isEmpty()) {
		p.setFont(_st.font->f);
		float64 btnWidth = float64(width()) / _buttons.size();
		for (int i = 0; i < _buttons.size(); ++i) {
			QRect btnRect(qRound(i * btnWidth), 0, qRound((i + 1) * btnWidth) - qRound(i * btnWidth), height());
			if (i == _selected) {
				p.fillRect(btnRect, _st.bgActive->b);
			} else if (i == _over) {
				p.fillRect(btnRect, a_bgOver.current());
			} else if (i == _wasOver) {
				p.fillRect(btnRect, a_bgWasOver.current());
			}
			p.setPen((i == _selected ? _st.activeColor : _st.textColor)->p);
			p.drawText(btnRect, _buttons[i], style::al_center);
		}
	}
	if (_st.border) {
		p.fillRect(0, 0, width() - _st.border, _st.border, _st.borderColor->b);
		p.fillRect(width() - _st.border, 0, _st.border, height() - _st.border, _st.borderColor->b);
		p.fillRect(_st.border, height() - _st.border, width() - _st.border, _st.border, _st.borderColor->b);
		p.fillRect(0, _st.border, _st.border, height() - _st.border, _st.borderColor->b);
	}
}
예제 #9
0
void EmojiButton::paintEvent(QPaintEvent *e) {
	Painter p(this);

	auto ms = getms();

	p.fillRect(e->rect(), st::historyComposeAreaBg);
	paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms);

	auto loading = a_loading.current(ms, _loading ? 1 : 0);
	p.setOpacity(1 - loading);

	auto over = isOver();
	auto icon = &(over ? _st.iconOver : _st.icon);
	icon->paint(p, _st.iconPosition, width());

	p.setOpacity(1.);
	auto pen = (over ? st::historyEmojiCircleFgOver : st::historyEmojiCircleFg)->p;
	pen.setWidth(st::historyEmojiCircleLine);
	pen.setCapStyle(Qt::RoundCap);
	p.setPen(pen);
	p.setBrush(Qt::NoBrush);

	PainterHighQualityEnabler hq(p);
	QRect inner(QPoint((width() - st::historyEmojiCircle.width()) / 2, st::historyEmojiCircleTop), st::historyEmojiCircle);
	if (loading > 0) {
		int32 full = FullArcLength;
		int32 start = qRound(full * float64(ms % st::historyEmojiCirclePeriod) / st::historyEmojiCirclePeriod), part = qRound(loading * full / st::historyEmojiCirclePart);
		p.drawArc(inner, start, full - part);
	} else {
		p.drawEllipse(inner);
	}
}
예제 #10
0
void Playback::updateState(const AudioPlaybackState &playbackState) {
	qint64 position = 0, duration = playbackState.duration;

	auto wasDisabled = _slider->isDisabled();
	if (wasDisabled) setDisabled(false);

	_playing = !(playbackState.state & AudioPlayerStoppedMask);
	if (_playing || playbackState.state == AudioPlayerStopped) {
		position = playbackState.position;
	} else if (playbackState.state == AudioPlayerStoppedAtEnd) {
		position = playbackState.duration;
	} else {
		position = 0;
	}

	float64 progress = 0.;
	if (position > duration) {
		progress = 1.;
	} else if (duration) {
		progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.;
	}
	if (duration != _duration || position != _position || wasDisabled) {
		auto animated = (duration && _duration && progress > _slider->value());
		_slider->setValue(progress, animated);
		_position = position;
		_duration = duration;
	}
	_slider->update();
}
예제 #11
0
void EmojiButton::paintEvent(QPaintEvent *e) {
	Painter p(this);

	uint64 ms = getms();
	float64 loading = a_loading.current(ms, _loading ? 1 : 0);
	p.setOpacity(_opacity * (1 - loading));

	p.fillRect(e->rect(), a_bg.current());

	p.setOpacity(a_opacity.current() * _opacity * (1 - loading));

	const style::sprite &i((_state & StateDown) ? _st.downIcon : _st.icon);
	if (!i.isEmpty()) {
		const QPoint &t((_state & StateDown) ? _st.downIconPos : _st.iconPos);
		p.drawSprite(t, i);
	}

	p.setOpacity(a_opacity.current() * _opacity);
	p.setPen(QPen(st::emojiCircleFg, st::emojiCircleLine));
	p.setBrush(Qt::NoBrush);

	p.setRenderHint(QPainter::HighQualityAntialiasing);
	QRect inner(QPoint((width() - st::emojiCircle.width()) / 2, st::emojiCircleTop), st::emojiCircle);
	if (loading > 0) {
		int32 full = 5760;
		int32 start = qRound(full * float64(ms % uint64(st::emojiCirclePeriod)) / st::emojiCirclePeriod), part = qRound(loading * full / st::emojiCirclePart);
		p.drawArc(inner, start, full - part);
	} else {
		p.drawEllipse(inner);
	}
	p.setRenderHint(QPainter::HighQualityAntialiasing, false);
}
예제 #12
0
void Slider::paintEvent(QPaintEvent *e) {
	QPainter p(this);

	p.fillRect(0, (height() - _st.thikness) / 2, width(), _st.thikness, _st.color->b);

	int32 x = qFloor(_sel * float64(width() - _st.bar.pxWidth()) / (_count - 1)), y = (height() - _st.bar.pxHeight()) / 2;
	p.drawPixmap(QPoint(x, y), App::sprite(), _st.bar);
}
예제 #13
0
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.);
}
예제 #14
0
파일: b2Timer.cpp 프로젝트: Cmdu76/Keengine
b2Timer::b2Timer()
{
	LARGE_INTEGER largeInteger;

	if (s_invFrequency == 0.0f)
	{
		QueryPerformanceFrequency(&largeInteger);
		s_invFrequency = float64(largeInteger.QuadPart);
		if (s_invFrequency > 0.0f)
		{
			s_invFrequency = 1000.0f / s_invFrequency;
		}
	}

	QueryPerformanceCounter(&largeInteger);
	m_start = float64(largeInteger.QuadPart);
}
예제 #15
0
파일: b2Timer.cpp 프로젝트: Cmdu76/Keengine
float32 b2Timer::GetMilliseconds() const
{
	LARGE_INTEGER largeInteger;
	QueryPerformanceCounter(&largeInteger);
	float64 count = float64(largeInteger.QuadPart);
	float32 ms = float32(s_invFrequency * (count - m_start));
	return ms;
}
예제 #16
0
    Vect Center () const
    {   if (0 == vertices . Count ()) return ZeroVect;

        Vect total = ZeroVect;
        for (int64 i = 0 ; i < vertices . Count () ; i++)
            total += vertices[i];

        return total / float64 (vertices . Count ());
    }
예제 #17
0
float64 PhotoData::progress() const {
	if (uploading()) {
		if (uploadingData->size > 0) {
			return float64(uploadingData->offset) / uploadingData->size;
		}
		return 0;
	}
	return full->progress();
}
예제 #18
0
void Slider::mouseMoveEvent(QMouseEvent *e) {
	if (_pressed) {
		int32 newSel = snap(qRound((_count - 1) * float64(e->pos().x() - _st.bar.pxWidth() / 2) / (width() - _st.bar.pxWidth())), 0, _count - 1);
		if (newSel != _sel) {
			_sel = newSel;
			update();
		}
	}
}
QString FillAmountAndCurrency(uint64 amount, const QString &currency) {
	static const auto ShortCurrencyNames = QMap<QString, QString> {
		{ qsl("USD"), QString::fromUtf8("\x24") },
		{ qsl("GBP"), QString::fromUtf8("\xC2\xA3") },
		{ qsl("EUR"), QString::fromUtf8("\xE2\x82\xAC") },
		{ qsl("JPY"), QString::fromUtf8("\xC2\xA5") },
	};
	static const auto Denominators = QMap<QString, int> {
		{ qsl("CLF"), 10000 },
		{ qsl("BHD"), 1000 },
		{ qsl("IQD"), 1000 },
		{ qsl("JOD"), 1000 },
		{ qsl("KWD"), 1000 },
		{ qsl("LYD"), 1000 },
		{ qsl("OMR"), 1000 },
		{ qsl("TND"), 1000 },
		{ qsl("BIF"), 1 },
		{ qsl("BYR"), 1 },
		{ qsl("CLP"), 1 },
		{ qsl("CVE"), 1 },
		{ qsl("DJF"), 1 },
		{ qsl("GNF"), 1 },
		{ qsl("ISK"), 1 },
		{ qsl("JPY"), 1 },
		{ qsl("KMF"), 1 },
		{ qsl("KRW"), 1 },
		{ qsl("MGA"), 1 },
		{ qsl("PYG"), 1 },
		{ qsl("RWF"), 1 },
		{ qsl("UGX"), 1 },
		{ qsl("UYI"), 1 },
		{ qsl("VND"), 1 },
		{ qsl("VUV"), 1 },
		{ qsl("XAF"), 1 },
		{ qsl("XOF"), 1 },
		{ qsl("XPF"), 1 },
		{ qsl("MRO"), 10 },
	};
	const auto currencyText = ShortCurrencyNames.value(currency, currency);
	const auto denominator = Denominators.value(currency, 100);
	const auto currencyValue = amount / float64(denominator);
	const auto digits = [&] {
		auto result = 0;
		for (auto test = 1; test < denominator; test *= 10) {
			++result;
		}
		return result;
	}();
	return QLocale::system().toCurrencyString(currencyValue, currencyText);
	//auto amountBucks = amount / 100;
	//auto amountCents = amount % 100;
	//auto amountText = qsl("%1,%2").arg(amountBucks).arg(amountCents, 2, 10, QChar('0'));
	//return currencyText + amountText;
}
예제 #20
0
//---------------------------------------------------------------------------
int64s TimeCode::ToMilliseconds()
{
    if (!FramesPerSecond)
        return 0;

    int64s MS=(int64s(Hours)     *3600
             + int64s(Minutes)   *  60
             + int64s(Seconds)        )*1000
             + float64_int64s((float64(Frames*(MustUseSecondField?2:1)+(IsSecondField?1:0)))*1000/(FramesPerSecond*(MustUseSecondField?2:1)));

    return IsNegative?-MS:MS;
}
예제 #21
0
PhotoSendBox::PhotoSendBox(const ReadyLocalMedia &img) : _img(img),
	_sendButton(this, lang(lng_send_button), st::btnSelectDone),
	_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
	a_opacity(0, 1) {

	connect(&_sendButton, SIGNAL(clicked()), this, SLOT(onSend()));
	connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));

	int32 maxW = 0, maxH = 0;
	for (PreparedPhotoThumbs::const_iterator i = img.photoThumbs.cbegin(), e = img.photoThumbs.cend(); i != e; ++i) {
		if (i->width() >= maxW && i->height() >= maxH) {
			_thumb = *i;
			maxW = _thumb.width();
			maxH = _thumb.height();
		}
	}
	int32 tw = _thumb.width(), th = _thumb.height();
	if (!tw || !th) {
		tw = th = 1;
	}
	_width = st::confirmWidth;
	_thumbw = _width - st::boxPadding.left() - st::boxPadding.right();
	if (_thumb.width() < _thumbw) {
		_thumbw = (_thumb.width() > 20) ? _thumb.width() : 20;
	}
	int32 maxthumbh = qRound(1.5 * _thumbw);
	_thumbh = qRound(th * float64(_thumbw) / tw);
	if (_thumbh > maxthumbh) {
		_thumbw = qRound(_thumbw * float64(maxthumbh) / _thumbh);
		_thumbh = maxthumbh;
		if (_thumbw < 10) {
			_thumbw = 10;
		}
	}
	_height = _thumbh + st::boxPadding.top() + st::boxFont->height + st::boxPadding.bottom() + st::boxPadding.bottom() + _sendButton.height();

	_thumb = QPixmap::fromImage(_thumb.toImage().scaled(_thumbw, _thumbh, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));

	resize(_width, _height);
}
예제 #22
0
QSize HistoryVideo::countOptimalSize() {
	if (_parent->media() != this) {
		_caption = Text();
	} else if (_caption.hasSkipBlock()) {
		_caption.updateSkipBlock(
			_parent->skipBlockWidth(),
			_parent->skipBlockHeight());
	}

	auto tw = ConvertScale(_data->thumb->width());
	auto th = ConvertScale(_data->thumb->height());
	if (!tw || !th) {
		tw = th = 1;
	}
	if (tw * st::msgVideoSize.height() > th * st::msgVideoSize.width()) {
		th = qRound((st::msgVideoSize.width() / float64(tw)) * th);
		tw = st::msgVideoSize.width();
	} else {
		tw = qRound((st::msgVideoSize.height() / float64(th)) * tw);
		th = st::msgVideoSize.height();
	}

	_thumbw = qMax(tw, 1);
	_thumbh = qMax(th, 1);

	auto minWidth = qMax(st::minPhotoSize, _parent->infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()));
	minWidth = qMax(minWidth, documentMaxStatusWidth(_data) + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x()));
	auto maxWidth = qMax(_thumbw, minWidth);
	auto minHeight = qMax(th, st::minPhotoSize);
	if (_parent->hasBubble() && !_caption.isEmpty()) {
		const auto captionw = maxWidth
			- st::msgPadding.left()
			- st::msgPadding.right();
		minHeight += st::mediaCaptionSkip + _caption.countHeight(captionw);
		if (isBubbleBottom()) {
			minHeight += st::msgPadding.bottom();
		}
	}
	return { maxWidth, minHeight };
}
예제 #23
0
void PlayerWidget::updateSelected() {
	QPoint pos(myrtlpoint(mapFromGlobal(_lastMousePos)));

	if (_down == OverVolume) {
		int32 delta = (pos.x() - _volumeRect.x()) - _downCoord;
		float64 startFrom = snap((_downCoord - ((_volumeRect.width() - st::playerVolume.pxWidth()) / 2)) / float64(st::playerVolume.pxWidth()), 0., 1.);
		float64 add = delta / float64(4 * st::playerVolume.pxWidth()), result = snap(startFrom + add, 0., 1.);
		if (result != cSongVolume()) {
			cSetSongVolume(result);
			emit audioPlayer()->songVolumeChanged();
			rtlupdate(_volumeRect);
		}
	} else if (_down == OverPlayback) {
		_downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.);
		rtlupdate(_playbackRect);
		updateDownTime();
	} else if (_down == OverNone) {
		bool inInfo = ((pos.x() >= _infoRect.x()) && (pos.x() < _fullRect.x() + _fullRect.width()) && (pos.y() >= _playRect.y()) && (pos.y() <= _playRect.y() + _playRect.height()));
		if (_prevAvailable && _prevRect.contains(pos)) {
			updateOverState(OverPrev);
		} else if (_nextAvailable && _nextRect.contains(pos)) {
			updateOverState(OverNext);
		} else if (_playRect.contains(pos)) {
			updateOverState(OverPlay);
		} else if (_closeRect.contains(pos)) {
			updateOverState(OverClose);
		} else if (_volumeRect.contains(pos)) {
			updateOverState(OverVolume);
		} else if (_repeatRect.contains(pos)) {
			updateOverState(OverRepeat);
		} else if (_duration && _playbackRect.contains(pos)) {
			updateOverState(OverPlayback);
		} else if (_fullAvailable && inInfo) {
			updateOverState(OverFull);
		} else if (_over != OverNone) {
			updateOverState(OverNone);
		}
	}
}
예제 #24
0
void Playback::updateState(const Player::TrackState &state) {
	qint64 position = 0, length = state.length;

	auto wasInLoadingState = _inLoadingState;
	if (wasInLoadingState) {
		_inLoadingState = false;
		if (_inLoadingStateChanged) {
			_inLoadingStateChanged(false);
		}
	}

	_playing = !Player::IsStopped(state.state);
	if (Player::IsStoppedAtEnd(state.state)) {
		position = state.length;
	} else if (!Player::IsStoppedOrStopping(state.state)) {
		position = state.position;
	} else {
		position = 0;
	}

	auto progress = 0.;
	if (position > length) {
		progress = 1.;
	} else if (length) {
		progress = snap(float64(position) / length, 0., 1.);
	}
	auto animatedPosition = position + (state.frequency * kPlaybackAnimationDurationMs / 1000);
	auto animatedProgress = length ? qMax(float64(animatedPosition) / length, 0.) : 0.;
	if (length != _length || position != _position || wasInLoadingState) {
		if (auto animated = (length && _length && animatedProgress > value())) {
			setValue(animatedProgress, animated);
		} else {
			setValue(progress, animated);
		}
		_position = position;
		_length = length;
	}
}
예제 #25
0
bool RadialAnimation::update(float64 prg, bool finished, TimeMs ms) {
	const auto iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
	const auto result = (iprg != qRound(a_arcEnd.to()));
	if (_finished != finished) {
		a_arcEnd.start(iprg);
		_finished = finished;
		_lastStart = _lastTime;
	} else if (result) {
		a_arcEnd.start(iprg);
		_lastStart = _lastTime;
	}
	_lastTime = ms;

	const auto dt = float64(ms - _lastStart);
	const auto fulldt = float64(ms - _firstStart);
	const auto opacitydt = _finished
		? (_lastStart - _firstStart)
		: fulldt;
	_opacity = qMin(opacitydt / st::radialDuration, 1.);
	if (anim::Disabled()) {
		a_arcEnd.update(1., anim::linear);
		if (finished) {
			stop();
		}
	} else if (!finished) {
		a_arcEnd.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear);
	} else if (dt >= st::radialDuration) {
		a_arcEnd.update(1., anim::linear);
		stop();
	} else {
		auto r = dt / st::radialDuration;
		a_arcEnd.update(r, anim::linear);
		_opacity *= 1 - r;
	}
	auto fromstart = fulldt / st::radialPeriod;
	a_arcStart.update(fromstart - std::floor(fromstart), anim::linear);
	return result;
}
예제 #26
0
void RadialAnimation::update(float64 prg, bool finished, uint64 ms) {
	int32 iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
	if (iprg != a_arcEnd.to()) {
		a_arcEnd.start(iprg);
		_lastStart = _lastTime;
	}
	_lastTime = ms;

	float64 dt = float64(ms - _lastStart), fulldt = float64(ms - _firstStart);
	_opacity = qMin(fulldt / st::radialDuration, 1.);
	if (!finished) {
		a_arcEnd.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear);
	} else if (dt >= st::radialDuration) {
		a_arcEnd.update(1, anim::linear);
		stop();
	} else {
		float64 r = dt / st::radialDuration;
		a_arcEnd.update(r, anim::linear);
		_opacity *= 1 - r;
	}
	float64 fromstart = fulldt / st::radialPeriod;
	a_arcStart.update(fromstart - std::floor(fromstart), anim::linear);
}
예제 #27
0
void StickerSetInner::paintEvent(QPaintEvent *e) {
	QRect r(e->rect());
	Painter p(this);

	if (_pack.isEmpty()) return;

	int32 rows = _pack.size() / StickerPanPerRow + ((_pack.size() % StickerPanPerRow) ? 1 : 0);
	int32 from = qFloor(e->rect().top() / st::stickersSize.height()), to = qFloor(e->rect().bottom() / st::stickersSize.height()) + 1;

	for (int32 i = from; i < to; ++i) {
		for (int32 j = 0; j < StickerPanPerRow; ++j) {
			int32 index = i * StickerPanPerRow + j;
			if (index >= _pack.size()) break;

			DocumentData *doc = _pack.at(index);
			QPoint pos(st::stickerPanPadding + j * st::stickersSize.width(), i * st::stickersSize.height());

			bool goodThumb = !doc->thumb->isNull() && ((doc->thumb->width() >= 128) || (doc->thumb->height() >= 128));
			if (goodThumb) {
				doc->thumb->load();
			} else {
				bool already = !doc->already().isEmpty(), hasdata = !doc->data.isEmpty();
				if (!doc->loader && doc->status != FileFailed && !already && !hasdata) {
					doc->save(QString());
				}
				if (doc->sticker->img->isNull() && (already || hasdata)) {
					if (already) {
						doc->sticker->img = ImagePtr(doc->already());
					} else {
						doc->sticker->img = ImagePtr(doc->data);
					}
				}
			}

			float64 coef = qMin((st::stickersSize.width() - st::msgRadius * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::msgRadius * 2) / float64(doc->dimensions.height()));
			if (coef > 1) coef = 1;
			int32 w = qRound(coef * doc->dimensions.width()), h = qRound(coef * doc->dimensions.height());
			if (w < 1) w = 1;
			if (h < 1) h = 1;
			QPoint ppos = pos + QPoint((st::stickersSize.width() - w) / 2, (st::stickersSize.height() - h) / 2);
			if (goodThumb) {
				p.drawPixmapLeft(ppos, width(), doc->thumb->pix(w, h));
			} else if (!doc->sticker->img->isNull()) {
				p.drawPixmapLeft(ppos, width(), doc->sticker->img->pix(w, h));
			}
		}
	}
	p.fillRect(0, _bottom - st::stickersAddOrShare, width(), st::stickersAddOrShare, st::emojiPanHeaderBg->b);
}
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 };
}
예제 #29
0
void PhotoCropBox::onSend() {
	QImage from(_img);
	if (_img.width() < _thumb.width()) {
		from = _thumb.toImage();
	}
	float64 x = float64(_cropx) / _thumbw, y = float64(_cropy) / _thumbh, w = float64(_cropw) / _thumbw;
	int32 ix = int32(x * from.width()), iy = int32(y * from.height()), iw = int32(w * from.width());
	if (ix < 0) {
		ix = 0;
	}
	if (ix + iw > from.width()) {
		iw = from.width() - ix;
	}
	if (iy < 0) {
		iy = 0;
	}
	if (iy + iw > from.height()) {
		iw = from.height() - iy;
	}
	int32 offset = ix * from.depth() / 8 + iy * from.bytesPerLine();
	QImage cropped(from.constBits() + offset, iw, iw, from.bytesPerLine(), from.format()), tosend;
	if (from.format() == QImage::Format_Indexed8) {
		cropped.setColorCount(from.colorCount());
		cropped.setColorTable(from.colorTable());
	}
	if (cropped.width() > 1280) {
		tosend = cropped.scaled(1280, 1280, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	} else if (cropped.width() < 320) {
		tosend = cropped.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	} else {
		tosend = cropped.copy();
	}

	emit ready(tosend);
	onClose();
}
예제 #30
0
void PlayerWidget::mousePressEvent(QMouseEvent *e) {
	QPoint pos(myrtlpoint(e->pos()));

	if (e->button() == Qt::LeftButton) {
		_down = OverNone;
		if (_song && _over == OverPlay) {
			playPausePressed();
			return;
		} else if (_over == OverPrev) {
			prevPressed();
		} else if (_over == OverNext) {
			nextPressed();
		} else if (_over == OverClose) {
			_down = OverClose;
		} else if (_over == OverVolume) {
			_down = OverVolume;
			_downCoord = pos.x() - _volumeRect.x();
			cSetSongVolume(snap((_downCoord - ((_volumeRect.width() - st::playerVolume.pxWidth()) / 2)) / float64(st::playerVolume.pxWidth()), 0., 1.));
			emit audioPlayer()->songVolumeChanged();
			rtlupdate(_volumeRect);
		} else if (_over == OverPlayback) {
			SongMsgId playing;
			AudioPlayerState playingState = AudioPlayerStopped;
			int64 playingPosition = 0, playingDuration = 0;
			int32 playingFrequency = 0;
			audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
			if (playing == _song && playingDuration) {
				if (playingState == AudioPlayerPlaying || playingState == AudioPlayerStarting || playingState == AudioPlayerResuming) {
					audioPlayer()->pauseresume(OverviewDocuments);
				}
				_down = OverPlayback;
				_downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.);
				_downDuration = playingDuration;
				_downFrequency = (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);

				rtlupdate(_playbackRect);
				updateDownTime();
			}
		} else if (_over == OverFull && _song) {
			if (HistoryItem *item = App::histItemById(_song.msgId)) {
				App::main()->showMediaOverview(item->history()->peer, OverviewAudioDocuments);
			}
		} else if (_over == OverRepeat) {
			_repeat = !_repeat;
			updateOverRect(OverRepeat);
		}
	}
}