2
0
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:
John Preston
2014-08-11 13:03:45 +04:00
parent f62db48251
commit d26afe1b64
29 changed files with 1274 additions and 491 deletions

View File

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