mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-09-03 16:15:13 +00:00
new photo viewer done, testing, added compressed checkbox in send-from-clipboard
This commit is contained in:
@@ -125,328 +125,3 @@ BackgroundWidget::~BackgroundWidget() {
|
||||
w->deleteLater();
|
||||
if (_hidden) _hidden->deleteLater();
|
||||
}
|
||||
|
||||
LayerWidget::LayerWidget(QWidget *parent, PhotoData *photo, HistoryItem *item) : QWidget(parent)
|
||||
, photo(photo)
|
||||
, video(0)
|
||||
, aBackground(0)
|
||||
, aOver(0)
|
||||
, iX(App::wnd()->width() / 2)
|
||||
, iY(App::wnd()->height() / 2)
|
||||
, iW(0)
|
||||
, iCoordFunc(anim::sineInOut)
|
||||
, aBackgroundFunc(anim::easeOutCirc)
|
||||
, aOverFunc(anim::linear)
|
||||
, hiding(false)
|
||||
, _touchPress(false)
|
||||
, _touchMove(false)
|
||||
, _touchRightButton(false)
|
||||
, _menu(0)
|
||||
{
|
||||
int32 x, y, w;
|
||||
if (App::wnd()->getPhotoCoords(photo, x, y, w)) {
|
||||
iX = anim::ivalue(x);
|
||||
iY = anim::ivalue(y);
|
||||
iW = anim::ivalue(w);
|
||||
}
|
||||
photo->full->load();
|
||||
setGeometry(0, 0, App::wnd()->width(), App::wnd()->height());
|
||||
aBackground.start(1);
|
||||
aOver.start(1);
|
||||
anim::start(this);
|
||||
show();
|
||||
setFocus();
|
||||
App::contextItem(item);
|
||||
|
||||
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
_touchTimer.setSingleShot(true);
|
||||
connect(&_touchTimer, SIGNAL(timeout()), this, SLOT(onTouchTimer()));
|
||||
}
|
||||
|
||||
LayerWidget::LayerWidget(QWidget *parent, VideoData *video, HistoryItem *item) : QWidget(parent)
|
||||
, photo(0)
|
||||
, video(video)
|
||||
, aBackground(0)
|
||||
, aOver(0)
|
||||
, iX(App::wnd()->width() / 2)
|
||||
, iY(App::wnd()->height() / 2)
|
||||
, iW(0)
|
||||
, iCoordFunc(anim::sineInOut)
|
||||
, aBackgroundFunc(anim::easeOutCirc)
|
||||
, aOverFunc(anim::linear)
|
||||
, hiding(false)
|
||||
, _touchPress(false)
|
||||
, _touchMove(false)
|
||||
, _touchRightButton(false)
|
||||
, _menu(0)
|
||||
{
|
||||
int32 x, y, w;
|
||||
if (App::wnd()->getVideoCoords(video, x, y, w)) {
|
||||
iX = anim::ivalue(x);
|
||||
iY = anim::ivalue(y);
|
||||
iW = anim::ivalue(w);
|
||||
}
|
||||
setGeometry(0, 0, App::wnd()->width(), App::wnd()->height());
|
||||
aBackground.start(1);
|
||||
aOver.start(1);
|
||||
anim::start(this);
|
||||
show();
|
||||
setFocus();
|
||||
App::contextItem(item);
|
||||
|
||||
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
_touchTimer.setSingleShot(true);
|
||||
connect(&_touchTimer, SIGNAL(timeout()), this, SLOT(onTouchTimer()));
|
||||
}
|
||||
|
||||
PhotoData *LayerWidget::photoShown() {
|
||||
return hiding ? 0 : photo;
|
||||
}
|
||||
|
||||
void LayerWidget::onTouchTimer() {
|
||||
_touchRightButton = true;
|
||||
}
|
||||
|
||||
bool LayerWidget::event(QEvent *e) {
|
||||
if (e->type() == QEvent::TouchBegin || e->type() == QEvent::TouchUpdate || e->type() == QEvent::TouchEnd || e->type() == QEvent::TouchCancel) {
|
||||
QTouchEvent *ev = static_cast<QTouchEvent*>(e);
|
||||
if (ev->device()->type() == QTouchDevice::TouchScreen) {
|
||||
touchEvent(ev);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
void LayerWidget::touchEvent(QTouchEvent *e) {
|
||||
switch (e->type()) {
|
||||
case QEvent::TouchBegin:
|
||||
if (_touchPress || e->touchPoints().isEmpty()) return;
|
||||
_touchTimer.start(QApplication::startDragTime());
|
||||
_touchPress = true;
|
||||
_touchMove = _touchRightButton = false;
|
||||
_touchStart = e->touchPoints().cbegin()->screenPos().toPoint();
|
||||
break;
|
||||
|
||||
case QEvent::TouchUpdate:
|
||||
if (!_touchPress || e->touchPoints().isEmpty()) return;
|
||||
if (!_touchMove && (e->touchPoints().cbegin()->screenPos().toPoint() - _touchStart).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
_touchMove = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::TouchEnd:
|
||||
if (!_touchPress) return;
|
||||
if (!_touchMove && App::wnd()) {
|
||||
Qt::MouseButton btn(_touchRightButton ? Qt::RightButton : Qt::LeftButton);
|
||||
QPoint mapped(mapFromGlobal(_touchStart)), winMapped(App::wnd()->mapFromGlobal(_touchStart));
|
||||
|
||||
QMouseEvent pressEvent(QEvent::MouseButtonPress, mapped, winMapped, _touchStart, btn, Qt::MouseButtons(btn), Qt::KeyboardModifiers());
|
||||
pressEvent.accept();
|
||||
mousePressEvent(&pressEvent);
|
||||
|
||||
QMouseEvent releaseEvent(QEvent::MouseButtonRelease, mapped, winMapped, _touchStart, btn, Qt::MouseButtons(btn), Qt::KeyboardModifiers());
|
||||
mouseReleaseEvent(&releaseEvent);
|
||||
|
||||
if (_touchRightButton) {
|
||||
QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, mapped, _touchStart);
|
||||
contextMenuEvent(&contextEvent);
|
||||
}
|
||||
}
|
||||
_touchTimer.stop();
|
||||
_touchPress = _touchMove = _touchRightButton = false;
|
||||
break;
|
||||
|
||||
case QEvent::TouchCancel:
|
||||
_touchPress = false;
|
||||
_touchTimer.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWidget::onMenuDestroy(QObject *obj) {
|
||||
if (_menu == obj) {
|
||||
_menu = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWidget::paintEvent(QPaintEvent *e) {
|
||||
bool trivial = (rect() == e->rect());
|
||||
|
||||
QPainter p(this);
|
||||
if (!trivial) {
|
||||
p.setClipRect(e->rect());
|
||||
}
|
||||
p.setOpacity(st::layerAlpha * aBackground.current());
|
||||
p.fillRect(rect(), st::layerBG->b);
|
||||
if (iW.current()) {
|
||||
if (!hiding) p.setOpacity(aOver.current());
|
||||
if (animating()) {
|
||||
const QPixmap &pm((photo ? (photo->full->loaded() ? photo->full : photo->thumb) : video->thumb)->pix());
|
||||
int32 h = pm.width() ? (pm.height() * iW.current() / pm.width()) : 1;
|
||||
p.drawPixmap(iX.current(), iY.current(), iW.current(), h, pm);
|
||||
if (!hiding) {
|
||||
p.setOpacity(1);
|
||||
p.setClipRect(App::wnd()->photoRect(), Qt::IntersectClip);
|
||||
p.drawPixmap(iX.current(), iY.current(), iW.current(), h, pm);
|
||||
}
|
||||
} else {
|
||||
const QPixmap &pm((photo ? (photo->full->loaded() ? photo->full : photo->thumb) : video->thumb)->pixNoCache(iW.current(), 0, !animating()));
|
||||
p.drawPixmap(iX.current(), iY.current(), pm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWidget::keyPressEvent(QKeyEvent *e) {
|
||||
if (!_menu && e->key() == Qt::Key_Escape) {
|
||||
startHide();
|
||||
} else if (photo && photo->full->loaded() && (e == QKeySequence::Save || e == QKeySequence::SaveAs)) {
|
||||
QString file;
|
||||
if (filedialogGetSaveFile(file, lang(lng_save_photo), qsl("JPEG Image (*.jpg);;All files (*.*)"), filedialogDefaultName(qsl("photo"), qsl(".jpg")))) {
|
||||
if (!file.isEmpty()) {
|
||||
photo->full->pix().toImage().save(file, "JPG");
|
||||
}
|
||||
}
|
||||
} else if (photo && photo->full->loaded() && (e->key() == Qt::Key_Copy || (e->key() == Qt::Key_C && e->modifiers().testFlag(Qt::ControlModifier)))) {
|
||||
QApplication::clipboard()->setPixmap(photo->full->pix());
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWidget::mousePressEvent(QMouseEvent *e) {
|
||||
if (_menu) return;
|
||||
if (e->button() == Qt::LeftButton) startHide();
|
||||
}
|
||||
|
||||
void LayerWidget::contextMenuEvent(QContextMenuEvent *e) {
|
||||
if (photo && photo->full->loaded() && !hiding) {
|
||||
if (_menu) {
|
||||
_menu->deleteLater();
|
||||
_menu = 0;
|
||||
}
|
||||
_menu = new QMenu(this);
|
||||
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
|
||||
_menu->addAction(lang(lng_context_copy_image), this, SLOT(copyContextImage()))->setEnabled(true);
|
||||
_menu->addAction(lang(lng_context_close_image), this, SLOT(startHide()))->setEnabled(true);
|
||||
if (App::contextItem()) {
|
||||
if (dynamic_cast<HistoryMessage*>(App::contextItem())) {
|
||||
_menu->addAction(lang(lng_context_forward_image), this, SLOT(forwardMessage()))->setEnabled(true);
|
||||
}
|
||||
_menu->addAction(lang(lng_context_delete_image), this, SLOT(deleteMessage()))->setEnabled(true);
|
||||
} else if ((App::self() && App::self()->photoId == photo->id) || (photo->chat && photo->chat->photoId == photo->id)) {
|
||||
_menu->addAction(lang(lng_context_delete_image), this, SLOT(deleteMessage()))->setEnabled(true);
|
||||
}
|
||||
_menu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
_menu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
connect(_menu, SIGNAL(destroyed(QObject*)), this, SLOT(onMenuDestroy(QObject*)));
|
||||
_menu->popup(e->globalPos());
|
||||
e->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWidget::deleteMessage() {
|
||||
if (!App::contextItem()) {
|
||||
if (App::self() && photo && App::self()->photoId == photo->id) {
|
||||
App::app()->peerClearPhoto(App::self()->id);
|
||||
} else if (photo->chat && photo->chat->photoId == photo->id) {
|
||||
App::app()->peerClearPhoto(photo->chat->id);
|
||||
}
|
||||
startHide();
|
||||
} else {
|
||||
App::wnd()->layerHidden();
|
||||
App::main()->deleteLayer();
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWidget::forwardMessage() {
|
||||
startHide();
|
||||
App::main()->forwardLayer();
|
||||
}
|
||||
|
||||
void LayerWidget::saveContextImage() {
|
||||
if (!photo || !photo->full->loaded() || hiding) return;
|
||||
|
||||
QString file;
|
||||
if (filedialogGetSaveFile(file, lang(lng_save_photo), qsl("JPEG Image (*.jpg);;All files (*.*)"), filedialogDefaultName(qsl("photo"), qsl(".jpg")))) {
|
||||
if (!file.isEmpty()) {
|
||||
photo->full->pix().toImage().save(file, "JPG");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWidget::copyContextImage() {
|
||||
if (!photo || !photo->full->loaded() || hiding) return;
|
||||
|
||||
QApplication::clipboard()->setPixmap(photo->full->pix());
|
||||
}
|
||||
|
||||
void LayerWidget::startHide() {
|
||||
hiding = true;
|
||||
aBackground.start(0);
|
||||
anim::start(this);
|
||||
}
|
||||
|
||||
void LayerWidget::resizeEvent(QResizeEvent *e) {
|
||||
int32 w = width() - st::layerPadding.left() - st::layerPadding.right(), h = height() - st::layerPadding.top() - st::layerPadding.bottom();
|
||||
int32 iw = (photo ? photo->full : video->thumb)->width(), ih = (photo ? photo->full : video->thumb)->height();
|
||||
if (!iw || !ih) {
|
||||
iw = ih = 1;
|
||||
} else {
|
||||
switch (cScale()) {
|
||||
case dbisOneAndQuarter: iw = qRound(float64(iw) * 1.25 - 0.01); ih = qRound(float64(ih) * 1.25 - 0.01); break;
|
||||
case dbisOneAndHalf: iw = qRound(float64(iw) * 1.5 - 0.01); ih = qRound(float64(ih) * 1.5 - 0.01); break;
|
||||
case dbisTwo: iw *= 2; ih *= 2; break;
|
||||
}
|
||||
}
|
||||
if (w >= iw && h >= ih) {
|
||||
iW.start(iw);
|
||||
iX.start(st::layerPadding.left() + (w - iw) / 2);
|
||||
iY.start(st::layerPadding.top() + (h - ih) / 2);
|
||||
} else if (w * ih > iw * h) {
|
||||
int32 nw = qRound(iw * float64(h) / ih);
|
||||
iW.start(nw);
|
||||
iX.start(st::layerPadding.left() + (w - nw) / 2);
|
||||
iY.start(st::layerPadding.top());
|
||||
} else {
|
||||
int32 nh = qRound(ih * float64(w) / iw);
|
||||
iW.start(w);
|
||||
iX.start(st::layerPadding.left());
|
||||
iY.start(st::layerPadding.top() + (h - nh) / 2);
|
||||
}
|
||||
if (!animating() || hiding) {
|
||||
iX.finish();
|
||||
iY.finish();
|
||||
iW.finish();
|
||||
}
|
||||
}
|
||||
|
||||
bool LayerWidget::animStep(float64 ms) {
|
||||
float64 dt = ms / (hiding ? st::layerHideDuration : st::layerSlideDuration);
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
aBackground.finish();
|
||||
aOver.finish();
|
||||
iX.finish();
|
||||
iY.finish();
|
||||
iW.finish();
|
||||
if (hiding) {
|
||||
QTimer::singleShot(0, App::wnd(), SLOT(layerHidden()));
|
||||
}
|
||||
res = false;
|
||||
} else {
|
||||
aBackground.update(dt, aBackgroundFunc);
|
||||
if (!hiding) {
|
||||
aOver.update(dt, aOverFunc);
|
||||
iX.update(dt, iCoordFunc);
|
||||
iY.update(dt, iCoordFunc);
|
||||
iW.update(dt, iCoordFunc);
|
||||
}
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
}
|
||||
|
||||
LayerWidget::~LayerWidget() {
|
||||
if (App::wnd()) App::wnd()->noLayer(this);
|
||||
delete _menu;
|
||||
}
|
||||
|
Reference in New Issue
Block a user